Problem/Motivation
Kernel tests have a datetime.time service but that does not have the request_stack as is the case during regular operations.
This makes it impossible to simulate different request times by modifying the (fake) current request in the request stack.
Steps to reproduce
Run something like
$requestStack = $this->container->get('request_stack');
$time = $this->container->get('datetime.time');
$request = $requestStack->getCurrentRequest();
$request->server->set('REQUEST_TIME', 123123123);
$this->assertEquals(123123123, $time->getRequestTime());
$request->server->set('REQUEST_TIME', 456456456);
$this->assertEquals(456456456, $time->getRequestTime());
in a kernel test and notice that the test fails.
Proposed resolution
Add the request_stack as an argument to the datetime.time service definition in kernel tests.
Remaining tasks
User interface changes
-
Introduced terminology
-
API changes
-
Data model changes
-
Release notes snippet
Comments
Comment #2
tstoecklerDid some archeology and this was actually removed in https://git.drupalcode.org/project/drupal/-/commit/8a034cda9b0508913e8ee... during development in #3113971: Replace REQUEST_TIME in services but I can't find any actual discussion.
Note that if people are turned off by the modifying of the request object in the example code in the issue summary, note that we currently do not have a generic, mutable version of the time service that could be used in tests, so this seems to be the most straightforward way to achieve that as far as I can tell.
Comment #3
tstoecklerComment #5
tstoecklerAdded a quick MR. Verified that this fixed a test as described in the issue summary. Didn't add an explicit test as that seems somewhat esoteric to me, but could be easily added in
KernelTestBaseTest::testRegister()if deemed appropriate.Comment #6
smustgrave commentedSeems to have broke some kernel tests?
Comment #7
tstoecklerYeah, haven't looked into it yet. Will try to fix them and then we can evaluate if this is actually a problematic change or if the tests that are now failing are just problematic.
Comment #8
tstoecklerSo I figured out what was going wrong in
ResourceObjectNormalizerCacherTest. The incrementing of the request time was not done correctly as it is inherently additive, i.e. what the code did was:But the assertions and code comments were doing:
The fact that the test passed nevertheless was due to the very bug being fixed here. The "current time" in the memory backend never actually got updated so the
MemoryBackend::prepareItem()never actually marked the items as invalid. And then the supposed "+800" test (which is actually a "+1300" test) accidentally tests the same code path that the supposed "+801 test" test should be testing. That one doesn't really make sense, though, anyway. When a cache item is expired it should not be returned, so the max age should not continuously be 0, instead it should be back to 800 because a new cache item was generated.Comment #9
tstoecklerI think that the fact that the only test that failed was actually failing precisely due to this bug (and some flawed assumptions) is a pretty good case that this is in fact a valid bug fix.
Comment #10
smustgrave commentedbut the new line adding the request_stack is removed?
Comment #11
tstoecklerOh right, forgot to point that out. I realized that whatever happens in
KernelTestBase::register()only acts as overrides of stuff incore.services.ymland with the added argument the definitions are the same so we might as well drop the entire override.As pointed out in the issue summary, the Git history is not very informative about why in particular this was added in the first place, so since tests pass without it, I think the most reasonable way forward is to just delete it.
Comment #12
smustgrave commentedBased on the explanation believe the change makes sense, pipeline is green
Comment #13
longwaveYep nice find, there is no need to override this here and it's found a genuine bug in a test.
Committed and pushed d2a88302e6b to main and e531888084f to 11.x. Thanks!