Problem/Motivation

- #2336597: Convert path aliases to full featured entities changes the path alias storage to use a new path_alias_field_data table instead of url_alias
- when visiting update.php to run the upgrade path provided by that issue, \Drupal\system\Controller\DbUpdateController::info() outputs a link to the maintenance page, which goes through the path alias processor
- the problem is that the alias path processor tries to use the new table, which doesn't exist yet

Proposed resolution

- don't try to process path aliases during database updates: use NullPathProcessorManager in UpdateServiceProvider
- make update path tests use the UpdateKernel while running the database updates and switch to the DrupalKernel when it's done

Remaining tasks

Review.

User interface changes

Nope.

API changes

Nope.

Data model changes

Nope.

Comments

amateescu created an issue. See original summary.

amateescu’s picture

Status: Active » Needs review
StatusFileSize
new4.5 KB

This should do it.

andypost’s picture

+++ b/core/lib/Drupal/Core/Update/UpdateServiceProvider.php
@@ -32,6 +32,8 @@ public function alter(ContainerBuilder $container) {
+    $container->register('path_processor_manager', 'Drupal\Core\PathProcessor\NullPathProcessorManager');

+++ b/core/tests/Drupal/FunctionalTests/Update/UpdatePathTestBase.php
@@ -327,6 +327,9 @@ protected function runUpdates() {
+    $this->initKernel($request, '\Drupal\Core\Update\UpdateKernel');

makes sense to use ::class to populate "use" with real usage of class

dawehner’s picture

I do agree. executing less APIs on update time reduces in general the chance that stuff goes wrong. I'm wondering whether we should open up an issue to talk about other APIs we could basically disable at that time.

  1. +++ b/core/lib/Drupal/Core/Test/FunctionalTestSetupTrait.php
    @@ -375,12 +375,15 @@ protected function initUserSession() {
    +  protected function initKernel(Request $request, $kernel_class = NULL) {
    +    $kernel_class = $kernel_class ?: DrupalKernel::class;
    

    Couldn't you use $kernel_class = DrupalKernel::class instead here?

  2. +++ b/core/tests/Drupal/FunctionalTests/Update/UpdatePathTestBase.php
    @@ -327,6 +327,9 @@ protected function runUpdates() {
    +    $request = Request::createFromGlobals();
    +    $this->initKernel($request, '\Drupal\Core\Update\UpdateKernel');
    

    Let's add some documentation why we choose this particular kernel.

amateescu’s picture

StatusFileSize
new5.17 KB
new1.96 KB

Thank you both for the reviews!

amateescu’s picture

Ugh, the interdiff doesn't include the change for #4.1, but it is included in the patch. It's just late here :)

The last submitted patch, 2: 3006086.patch, failed testing. View results

amateescu’s picture

StatusFileSize
new5.2 KB
new1022 bytes

It would help if we'd also assign the newly-built container.

The last submitted patch, 5: 3006086-5.patch, failed testing. View results

Status: Needs review » Needs work

The last submitted patch, 8: 3006086-8.patch, failed testing. View results

amateescu’s picture

Status: Needs work » Needs review
StatusFileSize
new20.37 KB
new15.17 KB

This interdiff is a possible way of fixing the test fails, but I didn't go through them all because I'm starting to doubt that it's a good solution..

wim leers’s picture

I think it makes a ton of sense that update.php does not try to resolve path aliases; it ought to depend on as little as possible.

Using NullPathProcessorManager makes sense.

AFAICT we need to change UpdatePathTestBase because it's actually already wrong in HEAD, it just happens to be that we never noticed problems caused by that bug. Correct?
I have to admit I don't understand why failures are happening or why #11 is fixing some of those failures. It's probably related to now finally using the correct kernel? In that case, wouldn't it be simpler to call \Drupal::setContainer($this->container) somewhere in UpdatePathTestBase?

Status: Needs review » Needs work

The last submitted patch, 11: 3006086-11.patch, failed testing. View results

amateescu’s picture

AFAICT we need to change UpdatePathTestBase because it's actually already wrong in HEAD, it just happens to be that we never noticed problems caused by that bug. Correct?

Exactly :)

wouldn't it be simpler to call \Drupal::setContainer($this->container) somewhere in UpdatePathTestBase?

That would've been nice, but it doesn't work :/

Discussed with @alexpott and @Berdir and the problem is that the test container and the site-under-test containers have got out-of-sync, but I still don't know the proper way to fix it.

berdir’s picture

There is no properer way to fix this IMHO

We are now creating two different container, which means $this->container is getting out of sync. And $this->container is the old one, so it would be the opposite direction than what #12 proposed. Which already seems to happen, or getting it again from $this->container wouldn't work.

But because specific services are kept as variables we have to update them once there is a new container.

amateescu’s picture

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

Funny enough, it turns out that we actually do use UpdateServiceProvider while running db update tests ... somehow, so there's no reason to mess with $this->container so much. The problem I was getting in #2336597-53: Convert path aliases to full featured entities is caused by accessing update.php before the update service provider kicks in, and it can be easily fixed by disabling path processing for \Drupal\FunctionalTests\Update\UpdatePathTestBase::$updateUrl.

This patch is enough to get all the update path tests green in #2336597: Convert path aliases to full featured entities. No interdiff because it's pointless.

wim leers’s picture

Hah!

+++ b/core/lib/Drupal/Core/Update/UpdateServiceProvider.php
@@ -32,6 +32,8 @@ public function alter(ContainerBuilder $container) {
+    $container->register('path_processor_manager', 'Drupal\Core\PathProcessor\NullPathProcessorManager');

+++ b/core/tests/Drupal/FunctionalTests/Update/UpdatePathTestBase.php
@@ -166,7 +166,7 @@ protected function setUp() {
-    $this->updateUrl = Url::fromRoute('system.db_update');
+    $this->updateUrl = Url::fromRoute('system.db_update', [], ['path_processing' => FALSE]);

Reading this … you'd think that either of these changes would be sufficient.

Why do we need both changes?

amateescu’s picture

The first change is needed so that when we display the contents of the update.php page we don't try to process the path to the maintenance mode page, and the second change is what I tried to explain in #16: don't process the path when navigating to update.php in tests :)

wim leers’s picture

Alright. Damn that's tricky!

+++ b/core/lib/Drupal/Core/Update/UpdateServiceProvider.php
@@ -32,6 +32,8 @@ public function alter(ContainerBuilder $container) {
+    $container->register('path_processor_manager', 'Drupal\Core\PathProcessor\NullPathProcessorManager');

Nit: Let's use NullPathProcessorManager::class. (@andypost also said this in #3.)

Status: Needs review » Needs work

The last submitted patch, 16: 3006086-15.patch, failed testing. View results

wim leers’s picture

Status: Needs work » Needs review
StatusFileSize
new1.88 KB
new3.06 KB

Bringing back a hunk from #8 to fix the failures.

wim leers’s picture

StatusFileSize
new1.09 KB
new3.68 KB

Addressed #3/#19.

wim leers’s picture

Title: update.php should not try to process path aliases » update.php should not process path aliases
amateescu’s picture

Thanks, Wim! I was in a rush to write the patch from #16 and it shows :)

wim leers’s picture

np!

jibran’s picture

This looks ready to me, just some observations.

  1. +++ b/core/modules/user/src/Plugin/LanguageNegotiation/LanguageNegotiationUserAdmin.php
    @@ -70,12 +70,12 @@ class LanguageNegotiationUserAdmin extends LanguageNegotiationMethodBase impleme
        *   The path processor manager.
    

    This comment is outdated now.

  2. +++ b/core/tests/Drupal/FunctionalTests/Update/UpdatePathTestBase.php
    @@ -166,7 +166,7 @@ protected function setUp() {
    +    $this->updateUrl = Url::fromRoute('system.db_update', [], ['path_processing' => FALSE]);
    

    It is worth adding comment why path processing is set to false.

amateescu’s picture

StatusFileSize
new3.54 KB
new666 bytes

Re #26:

1. It is not outdated, we are still working with a path processor manager, but since it doesn't have it's own interface we switched to use the one that's closest to the actual usage in \Drupal\user\Plugin\LanguageNegotiation\LanguageNegotiationUserAdmin::isAdminPath().

2. Done.

amateescu’s picture

amateescu’s picture

I think this is very much RTBC-able now. Any takers? :)

jibran’s picture

Status: Needs review » Reviewed & tested by the community

Thanks, it's ready.

alexpott’s picture

Status: Reviewed & tested by the community » Needs review

One question I have is what happens to URLs that are generated in update messages? As far as I know we have a few. Are we sure that we don't expect these to the processed?

amateescu’s picture

Status: Needs review » Reviewed & tested by the community
StatusFileSize
new1.73 KB
new3.28 KB

@alexpott, that's a very good question :)

Another option for this issue is to disable just the alias-based path processor, like we do in \Drupal\KernelTests\KernelTestBase::register(). That's much less invasive and should allow URLs to be generated properly in update messages.

catch’s picture

Status: Reviewed & tested by the community » Needs work

#26.2 was for a comment in UpdatePathTestBase, I think we need one there too.

alexpott’s picture

Issue tags: +Needs tests

Discussed a bit with @amateescu in slack. I was wondering if we could add a test that asserts that update messages with urls do not use aliases and that the same url is aliases afterwards. It might not be possible but I think it is worth trying.

amateescu’s picture

Status: Needs work » Reviewed & tested by the community
Issue tags: -Needs tests
StatusFileSize
new1.91 KB
new826 bytes
new4.55 KB

Added a comment.

I also tried to write a test for this but I couldn't get the mocked alias manager to work inside the site under test, it only works for URLs that are generated by the test itself. However, I think that any future patch that would undo this change will immediately break all of the update path tests, so we still have a lot of indirect test coverage...

alexpott’s picture

Status: Reviewed & tested by the community » Needs work

Discussed a bit more with @amateescu - he's going to try to use SQL to create the alias instead of using the mock. Yep we'll need to update this SQL when we move from 8.x to 9.x because we'll no longer have the path alias migration but if we don't do that then we would lose explicit test coverage of this change.

amateescu’s picture

Status: Needs work » Needs review
StatusFileSize
new3.69 KB
new5.59 KB

Here we go!

The last submitted patch, 37: 3006086-37-test-only.patch, failed testing. View results

Status: Needs review » Needs work

The last submitted patch, 37: 3006086-37.patch, failed testing. View results

amateescu’s picture

Status: Needs work » Needs review
StatusFileSize
new3.45 KB
new5.36 KB

Hmm, it seems we need separate patches for 8.6.x. The ones from #37 only apply to 8.7.x.

alexpott’s picture

@amateescu the test looks good to me - thanks agin for adding this coverage.

The last submitted patch, 40: 3006086-40-test-only-8.6.x.patch, failed testing. View results

amateescu’s picture

Status: Needs review » Reviewed & tested by the community

No problem :) Back to RTBC then.

alexpott’s picture

Status: Reviewed & tested by the community » Fixed

Committed 39578f4 and pushed to 8.7.x. Thanks!

Only committed to 8.7.x because whilst this is a bug fix the bug is only really exposed by work on-going in 8.7.x therefore I don't see any advantage to committing to 8.6.x. I might be wrong and if so we can commit #40 to 8.6.x.

diff --git a/core/tests/Drupal/FunctionalTests/Update/UpdatePathTestBaseTest.php b/core/tests/Drupal/FunctionalTests/Update/UpdatePathTestBaseTest.php
index 57ab172fc5..535d271d2e 100644
--- a/core/tests/Drupal/FunctionalTests/Update/UpdatePathTestBaseTest.php
+++ b/core/tests/Drupal/FunctionalTests/Update/UpdatePathTestBaseTest.php
@@ -5,8 +5,6 @@
 use Drupal\Component\Utility\Html;
 use Drupal\Component\Render\FormattableMarkup;
 use Drupal\Core\Database\Database;
-use Drupal\system\Tests\Routing\MockAliasManager;
-use Drupal\user\Entity\Role;
 
 /**
  * Tests the update path base class.

Removed unused uses on commit.

  • alexpott committed 39578f4 on 8.7.x
    Issue #3006086 by amateescu, Wim Leers, alexpott, jibran, andypost,...

Status: Fixed » Closed (fixed)

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

bkosborne’s picture

This issue created a bug where menu links that link to internal paths by alias will cause those paths to 404 after database updates are run (either via update.php or drush). I provided detailed steps to reproduce in the issue: #3075675: Route cache can become poisoned with invalid data during database updates, resulting in 404s.