As I commented in the bundles thread...
If you were to call drupal_container() from within a WebTestCase test, you would get the container of the main environment, not the test environment. So, if using run_tests.sh all that would be in it would be the config system services. However, when an actual request is made, e.g. using drupalGet() or drupalPost(), the full container for the test environment gets booted up for that request.
This is bad. The tests should have access to a fully-loaded DIC, with the particular services required by the test environment. Here's a first pass at providing this. Unfortunately it makes drupal_container() even uglier than it already was :-/
Also, I can't figure out how the testing container ends up having a 'request' service - it shouldn't, because that only ever gets set by HttpKernel when it's handling a request, but the testing kernel never handles a request. I am confused. Anyway, that is the only reason for the change in path.inc (because now this also fixes the problem described in #1719936: Theme API tests and Theme functions tests broken if run in a browser).
| Comment | File | Size | Author |
|---|---|---|---|
| #28 | 1727538_28.patch | 5.98 KB | chx |
| #28 | interdiff.txt | 1.01 KB | chx |
| #27 | 1727538_27.patch | 5.97 KB | chx |
| #26 | 1727538_26.patch | 5.95 KB | chx |
| #26 | interdiff.txt | 1.39 KB | chx |
Comments
Comment #2
katbailey commentedHmm, try this...
Comment #3
katbailey commentedComment #4
katbailey commentedI tried it with Crell's failing patch from #1606794-23: Implement new routing system, turns out the testing kernel is needed earlier than where I had it or stuff still explodes. Made that change plus some other minor fixes.
Comment #6
katbailey commentedOK, hopefully this will get us back to green.
Comment #7
damien tournoud commentedWhy don't we simply save the old container in setUp() and restoring in tearDown()?
The approach of keeping stuff around from the parent environment in the child environment in this patch is very at odd with how we handle the rest of the environment switching in the testing framework. Also, if I read this correctly, you are shutting down the testing kernel in the parent environment, not in the child, which is also really odd (which could lead to stuff like caches being set or flushed in the incorrect environment).
Comment #8
katbailey commentedUgh, yes it is quite possible I have over-complicated things here.
I guess we just need to make sure that the only difference between the DIC available from within the body of a test and the DIC being used when a drupalGet or drupalPost request is made, is that the latter has a request service (and therefore the request scope is active).
I'm not quite seeing what you mean - we create the kernel during setUp and destroy it during tearDown - why is this odd?
Anyway, I'll try to rework it tonight, unless someone else wants to have a go...
Comment #9
Crell commentedGiven the number of things this affects...
Comment #10
katbailey commentedMuch simpler, but should achieve exactly the same result...
Comment #12
katbailey commentedComment #13
katbailey commentedTo illustrate why we need this, I've changed the bundle test in this latest patch so that it is just asserting that the 'bundle_test_class' service exists, rather than what it currently does which is pretty crazy: it makes a drupalGet() request to a menu callback that checks the container for the service in question.
Also attaching that change to the bundles test as a separate patch to show that that test fails without the change introduced in this patch.
Comment #15
aspilicious commentedTempted to mark this rtbc...
Comment #16
Crell commentedI'll succumb to temptation. :-) #13 looks good to me. Thanks, Kat!
Comment #17
damien tournoud commentedIf I'm not mistaken, we are still shutting down the testing container while back inside the parent environment (with the parent database active, etc.):
This needs to move way higher in the tearDown() sequence.
Comment #18
alexpottGoing on the logic that tearDown() should done in the reverse order to setUp() I've moved the $this->kernel->shutdown(); to just before the simpletest database tables are deleted.
Also I can confirm that this patch fixes #1719936: Theme API tests and Theme functions tests broken if run in a browser
Comment #19
alexpottComment #20
xjm#1719936: Theme API tests and Theme functions tests broken if run in a browser is a critical and is postponed on this, so bumping this to critical.
Comment #21
chx commentedSo now we are use that if we are in the request scope then language_manager service exists?
I miss the wall of test explaining that while the 'prod' DrupalKernel in index.php has a request scope somehow the 'testing' kernel somehow doesn't and how this affects the DIC and so on.
The kernel is not booted in index.php. Is it necessary here?
Comment #22
chx commentedOh and...
Comment #23
chx commentedOh, per #13 it doesnt need tests. Thanks aspilicious for pointing this out. Still the black magic needs commenting.
Comment #24
katbailey commentedYes - the language_manager service is only available within the scope of a request and this is a much more reliable method for checking that. I had noticed that checking for
$container->has('request')was returning TRUE even when no request was actually being handled.The names 'prod' and 'testing' don't actually get used by anything right now - we could put 'ihazakernel' in here and it wouldn't make any difference to anything. However, we will probably start to make use of this when we get to compiling the container, and I imagine we'd want to avoid dumping the testing container to disk.
When the kernel handles a request, a check is made to see whether it is booted and, if not, it gets booted. We don't want to explicitly boot it because the page might end up being served from the cache (but this only matters when we move to using Symfony's HttpCache). But in the case of the testing kernel, it's never actually going to handle a request, so we need to boot it explicitly.
Let me know if you feel any of this warrants comments in the code.
Comment #25
chx commented> the language_manager service is only available within the scope of a request
But is it available always?
> somehow the 'testing' kernel somehow doesn't
This is not explained in your followup nor in code comment. Basically, I am asking why does your patch work??
Comment #26
chx commentedOK, I get it, thanks to the brief explanation by kat in IRC and a little digging in core. language_manager is registered byt the CoreBundle which also activates the request scope. The rest is explained in the patch. I daresay this is ready: I only added comments.
Comment #27
chx commentedTweaked the second paragraph more.
Comment #28
chx commentedbeejeebus tuned it further.
Comment #29
tim.plunkettRTBC +1 for the changes in #28
Comment #30
webchickI confess I don't quite follow this patch, but it has +1s from the right people and yay for unblocking testing. :)
Committed and pushed to 8.x. Yay!