Closed (fixed)
Project:
Drupal core
Version:
8.0.x-dev
Component:
simpletest.module
Priority:
Normal
Category:
Bug report
Assigned:
Unassigned
Issue tags:
Reporter:
Created:
1 Nov 2015 at 00:16 UTC
Updated:
21 Feb 2016 at 08:20 UTC
Jump to comment: Most recent, Most recent file
Comments
Comment #2
chx commentedComment #3
chx commentedComment #4
chx commentedComment #6
chx commentedComment #8
dawehnerIt is not a regression, this was an active design decision, see #356399: Optimize the route rebuilding process to rebuild on write
We had an issue for that, see #2338747: Move {router} out of system.install and create the table lazy
The patch doesn't actually patch the current kernel test base though, see
\Drupal\KernelTests\KernelTestBase::registerComment #9
fgmJust got bitten by this writing a test in a module using the KernelTestBase. As chx explained on IRC, such tests can solve the issue for now adding the following fragment, much like the patch does it:
Comment #10
chx commented> see \Drupal\KernelTests\KernelTestBase
I have nothing to do with those.
This should fix a few of them.
Comment #12
chx commentedAbout MenuLinkTreeTest. We hit RouteProvider::lazyLoadItself first when MenuLinkContent::postSave does $menu_link_manager->addDefinition($this->getPluginId(), $this->getPluginDefinition()); and that getPluginDefinition() call has a check on $url_object = $this->getUrlObject() which in turn leads to a routing request from Url::fromInternalUri.
During the router rebuild, MenuRouterRebuildSubscriber::menuLinksRebuild calls MenuLinkManager::rebuild which will call upon MenuTreeStorage::rebuild which saves all top links including our custom link in the tree storage. The link is now fully loadable and the addDefinition call which tries to load the link will promptly throw an exception. Commenting out the exception makes the test pass but it is obviously not the right thing to do.
A tentative fix is attached.
Comment #13
chx commentedIn short: checking the $update in postSave is wrong because it says nothing about the newness of the link as demonstrated. Instead, we can just check whether the definition exists and if it does then upgrade it.
Comment #14
dawehnerGiven that my productivity increased a lot with the new test base, here is an issue to also improve that: #2605956: Port #2605684 to the new KernelTest
Comment #15
dawehnerSounds like a good fix!
Comment #16
dawehnerMh, this comment now is not really exact anymore
This for without a body is valid PHP? Sounds like a while loop for me, which would be IMHO more readable
Unneeded suggestion: You could use RouterProvider::class here
Comment #17
chx commentedThis is about all the ones that needed to be removed I hope I have not overshot. Altogether some 49 removed and 51 remains. The followup will be more about DX than anything else, there are not many in kernelTNG tests to be removed.
Edit: next up I will do the table install from the new provider class as well without any schema change.
Comment #19
chx commentedThis version installs the router table on demand. There are more to be removed but I'm getting sleepy :)
Comment #21
chx commentedComment #23
chx commentedComment #24
chx commentedThere's only one installSchema call left in DbDumpCommandTest but that's followed by an insert call so it can't be avoided. I didn't roll an interdiff as there's no meaningful change.
Comment #25
dawehnerThis is clearly developer experience
This would better have a return statement
Comment #26
chx commentedthat's because it's not an event subscriber :) "simpletest.$original_id" is an event subscriber but this is not. I also folded some of the builder functionality into the semi-proxy class. Destruction is not needed. Let's hope this passes.
Comment #27
dawehnerAll tests pass so we are fine here. I hope we don't get bitten by the additional magic later, because well, this could be tricky for other people to debug.
On the other hand tests aren't part of any supported API.
The only problem I have with this is that this changes things from an explicit system to a every implicit system, which many people like, but I think most of the time implicitness
is problematic.
Given that these are test only patches, this is 'rc eligible'
Comment #28
chx commentedNo, there's a fix in MenuLinkContent and I pinged pwolanin over it.
Comment #29
dawehnerLet's talk about the change in MenuLinkContent ...
#2605684-12: Routing silently fails in kernel tests describes the problem pretty clear. The solution for this problem is really elegant as it removes the complexity of the code and by that remove the potential
edge cases.
Comment #30
chx commentedThanks. I didn't realize you were a menu maintainer too :)
Comment #31
pwolanin commentedIt looks like you are throwing out the check on the $update flag?
Comment #32
chx commentedYes. It is meaningless to do so because as described in #12 the link changes from "new" to "existing" by calling the plugin definition. Just check whether there's a definition.
Comment #33
chx commentedOpsie, sorry! Bad status, wanted NR.
Comment #34
dawehner@pwolanin
So yeah
$menu_link_manager->getDefinition($this->getPluginId(), FALSE)will return TRUE, if there is already an entry in the menu_tree and FALSE otherwise, whichis IMHO exactly what we want to check.
Comment #35
pwolanin commentedOk, so it sounds like this just needs some code comments explaining that logic and why the flag is (should be) ignored?
Comment #36
chx commentedAdded wall of text no other change
Comment #37
pwolanin commentedI looked quickly at the call chain but not enough to understand what's happening in detail. Something seems wrong there if we get that mysterious saving behavior, but at least this added comment makes it possible to understand the code.
Comment #38
chx commentedLet me attempt again.
What's a plugin definition for a menu link?
the tree storage entry. Where do we save definitions aside from postSave? MenuTreeStorage::rebuild has this:
Where does $definitions come from? Why, it's the
$definitions = $this->getDiscovery()->getDefinitions();call inMenuLinkManager::rebuildwhich is , in turn, called fromMenuRouterRebuildSubscriber::menuLinksRebuildSo then what definitions are there? Many, but for us the most important is
MenuLinkContentDeriver.So
MenuLinkContentDeriverloads from entity storageMenuTreeStorage::rebuildComment #39
chx commentedFollowing up on an IRC discussion: this is a testing artefact but there's nothing stopping a route provider to trigger a rebuildIfNeeded. One could even argue it's a bug not to do so but that's for a different issue.
Comment #40
dawehnerThis is still RTBC
Comment #41
xjmCan we split the MenuLinkContent fix out into its own issue that blocks this one?
Both parts would potentially be eligible for a patch release, so @effulgentsia and I don't think this needs to be done during RC. If this issue does actually contain something disruptive that wouldn't be eligible for a patch release, let's add that to the issue summary.
Comment #42
chx commentedI thought of it but you can't test it without this issue or not easily.
Comment #43
chx commentedThis is the absolute minimal version of this patch: just MenuLinkContent, TestServiceProvider and RouteProvider. We can do the rest in a test only followup. This much is enough to trigger and fix the MLC bug.
Comment #44
chx commentedComment #45
dawehnerI am still convinced about it, given that it makes things easier for people to write tests.
Comment #47
chx commentedBot fail.
Comment #48
catchIt looks like this change could cause equivalent failures in contrib/custom modules doing the same thing.
So the question for me is:
- is this a bug in MenuLinkContent that will affect production sites, that is exposed by the test coverage
- or, is it something that will only fail in tests
If it's the latter, this starts to look 8.1.x-ish to me - since we're forcing changes to production code in a patch release. Back to CNR to figure out which it is.
Comment #49
chx commentedIt's internal. By the time external modules
get a chance the behavior is consistent, the definition/tree storage is updated.
You only have a problem if you change the route provider to rebuild on demand. Modules can't get into trouble.
Comment #50
chx commentedmost recent example of hitting this and needing to manually rebuild was in #2598376: d6_user_settings migration user_register constants don't seem to line up.
Comment #51
alexpott@catch, @effulgentsia and I discussed this and we feel the benefits outweigh the risks. Committed 817ee92 and pushed to 8.0.x. Thanks!
Comment #55
dawehnerLet's remove that in 8.1.x again, see #2605956: Port #2605684 to the new KernelTest