Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
See https://www.drupal.org/pift-ci-job/541874 and https://www.drupal.org/pift-ci-job/542382
We need to find out why this goes wrong on this environment and improve the test.
Comment | File | Size | Author |
---|---|---|---|
#24 | 2832013-24.patch | 1.46 KB | catch |
#21 | 2832013-21.patch | 2.04 KB | michielnugter |
#21 | interdiff-16-21.txt | 851 bytes | michielnugter |
#16 | 2832013-16.patch | 2.13 KB | michielnugter |
#16 | interdiff-14-16.txt | 2.14 KB | michielnugter |
Comments
Comment #2
Wim LeersSo, it's not just
CommentHalJsonAnonTest
. It's\Drupal\Tests\rest\Functional\EntityResource\Comment\CommentResourceTestBase::testPostDxWithoutCriticalBaseFields()
that fails on PHP 5.6+MySQL 5.5, for every subclass:ComentHalJsonAnonTest
ComentHalJsonBasicAuthTest
ComentHalJsonCookieTest
ComentJsonAnonTest
ComentJsonBasicAuthTest
ComentJsonCookieTest
The failing line:It seems that for some reason, Drupal 8 does not generate a 500 response with a response body containingA fatal error occurred: Internal Server Error
on PHP 5.6. On PHP 5.5 and PHP 7, it does. But on 5.6, it outputs this instead:In other words, it seems that Drupal 8 on PHP 5.6 does not succeed in hiding the fatal error from the end user, unlike 5.5/7.See #5.
, for which we have this issue: #2820364: Entity + Field + Property validation constraints are processed in the incorrect order.
Comment #3
Wim LeersReproduced locally on PHP 5.6.27:
Now I can determine the root cause.
Comment #4
dawehnerI think testing for 500s is tricky, as these errors might depend on PHP configurations. I think commenting this test out with the todo might be not the worst idea.
Comment #5
Wim LeersMy analysis in #2 pointed to the wrong code.
This is the relevant test code:
And it's that very long line below
// This happens on Wim's local machine.
that is failing on PHP 5.6. That try/catch is to show the difference between testbot (where the "catch" was not being used) and my local machine (where the "catch" was necessary). It seems like testbot does need that "catch" in the case of PHP 5.6, but not PHP 5.5 or PHP 7. The "catch" therefore describes inconsistencies in PHP execution behavior". But it seems like testbot fails in an even different way than my local machine. Except on PHP 5.6, it seems to match.Investigating further…
Comment #6
Wim LeersSo the difference is that PHP 7 converts a fatal error to a 500 response, but PHP 5.6 (and 5.5) convert it to a 200 response. All three PHP runtimes actually produce the same fundamental error.
There are two problems here:
\Drupal\Core\Test\HttpClientMiddleware\TestHttpClientMiddleware
behaves differently in PHP 5 and PHP 7.Attached patch contains small modifications to prove these claims.
This should result in this output:
Comment #7
Wim Leers#6.2 accuses
\Drupal\Core\Test\HttpClientMiddleware\TestHttpClientMiddleware
inappropriately. There's nothing it can do about that. Because it can only throw exceptions for those things that PHP itself threw exceptions for during the request. Any exceptions are transformed toX-Drupal-Assertion-<ID>
headers. In this case:… but that's only going to happen on PHP 7. And
TestHttpClientMiddleware
of course can only throw exceptions for those response headers it finds. So the difference in behavior I perceived in #6 is entirely attributable to PHP 7 vs PHP 5 (able to catch fatal errors vs not).It could be argued that it's up to D8's error handler to ignore PHP 7 catchable fatal errors for consistency with PHP 5, but there are probably good reasons not do to that.
Comment #8
Wim LeersComment #9
Wim LeersAnd here then is the solution, to assert the fatal errors correctly on both PHP 5 & 7.
Now working on #2820364: Entity + Field + Property validation constraints are processed in the incorrect order, which will remove the need for all this entirely. In the mean time, these assertions ensure that PHP 5.5, PHP 5.6 and PHP 7.0 all fail in the same way.
Comment #12
alexpottShould this if have an else and fail if we get there - or should it not exist at all?
Comment #13
Wim LeersHm, this is interesting. Drupal CI's PHP 5.5 is apparently configured to serve a 500 response instead of the default 200 response for fatal errors. But, we honestly don't care too much about the status code. It's the fact that there's a fatal error … that we do care about.
So, this should do the trick.
Comment #14
Wim Leers#12: good point! Done.
Comment #15
Wim LeersThis also applies to Drupal 8.2 BTW.
Also queuing #14 to be tested against 8.2.x, and also against PHP 5.5, 5.6 and 7.0.
Comment #16
michielnugter CreditAttribution: michielnugter as a volunteer and at Synetic commentedI'm having a little trouble with the 2 different approaches for validating the error message. For php < 7.0 only parts of the error are validated. For php >= 7.0 the complete error message is validated. If even a single line is added to CommentNameConstraintValidator.php the test will pass in php < 7.0 and fail in php >= 7.0, to me for no good reason.
I changed it a little to use the same logic. I don't have php 7 or 5.6 running yet so the attached patch might fail, sorry for that.
Comment #19
Wim LeersHm, still failing on 5.5. It seems like Drupal CI's PHP 5.5 is doing some strange things…
(Ironic that the problem now "jumped" from 5.6 to 5.5…)
Comment #21
michielnugter CreditAttribution: michielnugter as a volunteer and at Synetic commentedI can't really wrap my head around the exact problem as it's impossible to reproduce locally (on php 5.5).
As I saw discussed on IRC: it's the difference in the way the error is reported.
The basic variations are something like:
- Call to a member function get() on null
- Call to a member function get() on CommentNameConstraintValidator
How important is it to check on the CommentNameConstraintValidator? I removed that check form this patch, let's see if that fixes the problem.
Comment #23
catchI think we should comment out the assertions to get HEAD back to passing on 5.6, then open another issue to uncomment them, but that is likely to require #2688999: Default all responses to 500 before any code is run so PHP will throw 500's on FATAL errors really.
Comment #24
catchHere's a patch for that. The existing @todo is sufficient if this is going to move to a 422 eventually anyway.
Comment #25
xjm#24 works for me to hotfix the test without rolling back the whole patch, so long as it's explicitly in scope for the followup.
I queued all the environments.
Comment #26
catchThe postgres fail is
to save people looking.
Comment #27
Wim LeersYep, #24 is the rougher option that @dawehner proposed in #4. That is obviously guaranteed to work. I'd have preferred to strictly validate the fatal error, but it's really a nit. We can indeed comment its assertions, and the follow-up (#2820364: Entity + Field + Property validation constraints are processed in the incorrect order) A) definitely removes all that hackiness and B) is already in progress!
So, moving this to RTBC.
For future readers: the fail catch mentioned in #26 is a known current random fail: #2830485: \Drupal\Tests\outside_in\FunctionalJavascript\OutsideInBlockFormTest fails randomly.
Comment #28
alexpottCommitted and pushed f7aed20 to 8.3.x and d34d9dc to 8.2.x. Thanks!
It seems like we have all the followups planned - we could add @todos but the test fails are worse... moving on.
Comment #31
Wim LeersYep, all follow-ups planned!
Comment #33
apaderno