Problem/Motivation

During Drupal 8, we added support for \Drupal::MINIMUM_SUPPORTED_PHP, which defines a PHP version that allows sites to run, but displays warnings on update and errors on the status report for existing sites. (New installations are not allowed except within the test runner.)

However, numerous tests now fail when MINIMUM_SUPPORTED_PHP is actually used, either due to issues with the test or possible regressions in HEAD.

One of these tests is Drupal\Tests\system\Functional\UpdateSystem\NoPreExistingSchemaUpdateTest. It fails because the message about missing schema information is added to the first page load in update.php, whatever that may be. If the requirements warning page appears (as it will with an old PHP version), the message is displayed on that page, rather than the main update.php intro. Since the test asserts that the message is displayed on the latter screen, it fails on a PHP version below \Drupal::MINIMUM_SUPPORTED_PHP.

Proposed resolution

We discussed whether to change the actual functionality in HEAD so that the message was consistently displayed on the main screen of update.php. (See #13, #15, and comments from the previous MR below that.) This approach was not reliable because it would not display the message if the user didn't immediately continue past the requirements warnings, and also was complicated to implement reliably when updates were run from other code paths (e.g. drush).

The current approach is to simply change the test by moving the assertion earlier, so that it will pass regardless of whether the next screen is the warning screen or the normal intro.

There are three MRs:

  1. 3265378-FAIL increases the minimum supported PHP version so that the PHP 7.3 test environment will expose the bug, plus skips some other test failures covered in other issues.
  2. 3265378-move-assertion combines the failing version with the change to the test to prove that the issue is resolved.
  3. 3265378-fix-only is the version for commit.

Remaining tasks

NR.

User interface changes

N/A

API changes

N/A

Data model changes

N/A

Release notes snippet

Issue fork drupal-3265378

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

xjm created an issue. See original summary.

xjm’s picture

Status: Active » Needs review
xjm’s picture

daffie’s picture

Status: Needs review » Needs work

The MR only is showing that it is failing. Where is the one with the fix?

xjm’s picture

@daffie, sorry, I forgot that MRs and/or alternate environment tests don't automatically set issues NW for failures. This was just a bit of TDD. I've been debugging locally and the browser output makes it appear that either HEAD is actually broken or the test makes faulty assumptions. Will post more detail later on this and #3265377: Fix LocaleTranslatedSchemaDefinitionTest when MINIMUM_SUPPORTED_PHP is used.

xjm’s picture

Issue summary: View changes
FileSize
232.38 KB
184.93 KB
198.13 KB

xjm’s picture

So the test failure is:

1) Drupal\Tests\system\Functional\UpdateSystem\NoPreExistingSchemaUpdateTest::testNoPreExistingSchema
Behat\Mink\Exception\ResponseTextException: The text "Schema information for module update_test_no_preexisting was missing from the database. You should manually review the module updates and your database to check if any updates have been skipped up to, and including, update_test_no_preexisting_update_8001()." was not found anywhere in the text of the current page.

/var/www/html/vendor/behat/mink/src/WebAssert.php:785
/var/www/html/vendor/behat/mink/src/WebAssert.php:262
/var/www/html/core/tests/Drupal/Tests/WebAssert.php:898
/var/www/html/core/modules/system/tests/src/Functional/UpdateSystem/NoPreExistingSchemaUpdateTest.php:73
/var/www/html/vendor/phpunit/phpunit/src/Framework/TestResult.php:703

ERRORS!
Tests: 1, Assertions: 10, Errors: 1.

The thing about this test is that it is already using $this->updateRequirementsProblem() correctly:

    $this->drupalGet($update_url);
    $this->updateRequirementsProblem();

    $schema = \Drupal::service('update.update_hook_registry')->getAllInstalledVersions();
    $this->assertArrayHasKey('update_test_no_preexisting', $schema);
    $this->assertEquals('8001', $schema['update_test_no_preexisting']);
    // The schema version has been fixed, but the update was never run.         
    $this->assertFalse(\Drupal::state()->get('update_test_no_preexisting_update_8001', FALSE));
    $this->assertSession()->pageTextContains('Schema information for module update_test_no_preexisting was missing from the database. You should manually review the module updates and your database to check if any updates have been skipped up to, and including, update_test_no_preexisting_update_8001().');

On PHP 7.4

This is what the HTML output from the test is supposed to look like, on PHP 7.4:

Screenshot of the HTML browser output, showing the above page text at the top of the initial screen of update.php.

On PHP 7.3

When the test is run on PHP 7.3, there are two screens instead of one, from successfully clicking past the warning:

Screenshot of the HTML browser output, showing a warning that PHP 7.3 is too old along with the message about the schema

Screenshot of the HTML browser output, lacking the text at the top of update.php

Note that the text from the final assertion is shown on the first page, with the PHP warning, instead of the second. So this is sort of an actual bug in core.

We could just change the test so that the assertion is called earlier, when it will pass regardless of whether the PHP is below the supported minimum or not, as is done in 3265378-move-assertion. However, I'm not sure that's the correct fix because the message about the schema information makes more sense in the context of the main update.php screen. If it's presented on the warnings screen, there's too much different information for the site owner to address at once.

xjm’s picture

The message is added at the end of _update_fix_missing_schema(), which in turn is called from update_check_requirements():

function update_check_requirements() {

  // Because this is one of the earliest points in the update process,
  // detect and fix missing schema versions for modules here to ensure
  // it runs on all update code paths.
  _update_fix_missing_schema();

  // Check requirements of all loaded modules.
  $requirements = \Drupal::moduleHandler()
    ->invokeAll('requirements', [
    'update',
  ]);
  $requirements += update_system_schema_requirements();
  return $requirements;
}

Because the message is added before the requirements warnings are handled, this means it shows up on the warnings screen, rather than the main database update page.

To fix this, we'd have to additionally add some custom code in DbUpdateController::handle() to check whether the message is loaded, save it, unset it, and reset it after the requirements warning happens...

Or, to avoid some of that we could move the logic directly into DbUpdateController::handle(), which would allow us to check for the problematic condition early, but then raise the message later after the warning handling. I'll try to code that up.

xjm’s picture

Issue summary: View changes
Status: Needs work » Needs review
FileSize
115.39 KB
225.04 KB

3265378-move-messages implements #11, by moving the messages to state when there are warnings and fetching them from state when the user has clicked past the warnings.

On PHP 7.3, the message is no longer displayed on the warnings page:

Instead, it is moved to the correct screen:

So the question is whether to make that change, which means more code paths to clean up later in the handler when #3130037: system.schema information gets out of sync with module list is fixed, or just to live with the message being on the wrong page and change the test.

xjm’s picture

Issue summary: View changes
FileSize
186.03 KB
xjm’s picture

Issue summary: View changes

OTOH maybe displaying the warning on the first screen is correct, in case they never click past the warning? update.php has already attempted to fix the schema at the start, so something has changed and maybe we should inform the site owner then.

Not sure which approach is best. Updating the IS with both.

xjm’s picture

catch’s picture

Left a comment on one of the MRs - if that comment is correct, then I'd be tempted to go for the test-only change here.

xjm’s picture

Issue summary: View changes
xjm’s picture

Issue summary: View changes
xjm’s picture

Issue summary: View changes
daffie’s picture

Status: Needs review » Reviewed & tested by the community

The 3 MR's convince me that the fix is the right one.
For me it is RTBC.

  • catch committed eb75b5e on 10.0.x
    Issue #3265378 by xjm: Fix NoPreExistingSchemaUpdateTest when...

  • catch committed 5dca800 on 9.4.x
    Issue #3265378 by xjm: Fix NoPreExistingSchemaUpdateTest when...

  • catch committed cf3064d on 9.3.x
    Issue #3265378 by xjm: Fix NoPreExistingSchemaUpdateTest when...
catch’s picture

Status: Reviewed & tested by the community » Fixed

Committed eb75b5e and pushed to 10.0.x. Thanks! Also cherry-picked to 9.4.x and 9.3.x

Status: Fixed » Closed (fixed)

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