Problem/Motivation

Spin-off from #3087644: Remove Drupal 8 updates up to and including 88**.

Once we've removed older Drupal 8 updates from Drupal 9, it will be necessary for all new updates added to the code base to be tested from a Drupal 8.8.x starting point, since Drupal 9 won't be able to run updates from 8.7.x or earlier databases any more.

Our Drupal 8 test coverage is reliant on database dumps, but we did recently add #3031379: Add a new test type to do real update testing which provides an alternative way to test updates - by installing Drupal then updating the install instead of loading a database dump.

Whichever we use, we need boilerplate test coverage for running updates. Something like the following for basic test coverage:

- both minimal and standard install profiles. (and standard+).

- The source site/database needs to have content created in it (nodes, taxonomy terms, users) so that there's actually something to update in there.

Marking critical because it is going to block either the Drupal 9 beta, or adding new upgrade paths to Drupal 8, depending on whether this issue or the update removal one happens first. Also if we add new updates to 8.8.x using our old testing harness, we'll need to refactor the test coverage for them anyway, so really it should block new updates either way.

Proposed resolution

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

New database dumps have been added for upgrade path testing from 8.8.x onwards. This is in preparation from updates prior to Drupal 8.8.0 being removed from Drupal 9.

CommentFileSizeAuthor
#44 filled-db-8-to-8.8.x.diff3.44 MBjibran
#44 bare-db-8-to-8.8.x.diff2.05 MBjibran
#42 3089900-42.patch714.32 KBjibran
#42 interdiff-4a3fe1.txt1.35 KBjibran
#38 3089900-38.patch714.2 KBjibran
#38 interdiff-bd24b6.txt1.73 KBjibran
#37 3089900-37.patch714.42 KBjibran
#37 interdiff-42df00.txt1.88 KBjibran
#35 3089900-35.patch714.64 KBjibran
#35 interdiff-1e96d7.txt1.48 KBjibran
#28 3089900-2-28.patch713.67 KBalexpott
#25 3089900-2-25.patch715.71 KBalexpott
#24 3089900-2-24.patch728.5 KBalexpott
#24 3089900-to-review-24.patch3.42 KBalexpott
#24 23-24-interdiff.txt10.93 KBalexpott
#23 3089900-23.patch744.22 KBjibran
#23 3089900-23-do-not-test.patch13.41 KBjibran
#23 interdiff-43441d.txt2.8 KBjibran
#21 3089900-21.patch741.35 KBjibran
#21 3089900-21-do-not-test.patch10.61 KBjibran
#21 interdiff-e03ea6.txt76.95 KBjibran
#13 3089900-13.patch797.22 KBjibran
#13 3089900-13-do-not-test.patch33.52 KBjibran
#13 interdiff-3ad623.txt26.65 KBjibran
#11 3089900-11.patch772.41 KBjibran
#11 3089900-11-do-not-test.patch9.57 KBjibran
#11 update-db-dump.txt1.08 KBjibran
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

catch created an issue. See original summary.

catch’s picture

Issue summary: View changes
alexpott’s picture

So we could theoretically install umami on 8.8.x and update it to Drupal 9 and run its tests - that'd give us multilingual content to test against. But OTOH we said we'd never support umami upgrades and reserve the right to break things. So maybe we could install umami, change the theme to another theme, hack the profile.... ugh.. I dunno maybe that'd work.

catch’s picture

Probably the quickest way to get an 8.8 database dump would be to install the existing test database dumps, update them to 8.8.x, then redump. I don't think we should keep doing that forever, but one advantage is it does give us an example of a database with a long lifespan.

jibran’s picture

@catch

- 8.8: This makes sense. I think we can write a test to do that for us and it will generate the new DB dump at the end.
- 8.9: Are we going to use above D8.8 DB dumps for this branch as well? Do we want to do that for all the dumps in the code atm?
- 9.0: In #3087644: Remove Drupal 8 updates up to and including 88**, I'm adding a new D9 DB dump to make sure upgrade path tests keep working in D9. We can bring those parts over here unless we want to keep those there and forward port the D8.8 dumps to D9?

catch’s picture

@jibran I think it's worth having both 8.8 and 9.0 database dumps tested against 9.x - for example an 8.8 database dump might have a reference to something that's going to be removed in 9.x that we haven't accounted for. So for me I would move those over here (should also mean less to review in the removal patch).

jibran’s picture

Assigned: Unassigned » jibran

Going to have a crack at this.

jibran’s picture

We have following DB dumps.

ll core/modules/system/tests/fixtures/update/*.gz
core/modules/system/tests/fixtures/update/drupal-8.0.0-rc1-filled.standard.entity_test_update_mul.php.gz
core/modules/system/tests/fixtures/update/drupal-8.0.0-rc1-filled.standard.entity_test_update_mul_rev.php.gz
core/modules/system/tests/fixtures/update/drupal-8.0.0-rc1-filled.standard.entity_test_update.php.gz
core/modules/system/tests/fixtures/update/drupal-8.2.0.bare.standard_with_entity_test_revlog_enabled.php.gz
core/modules/system/tests/fixtures/update/drupal-8.4.0.bare.standard.php.gz
core/modules/system/tests/fixtures/update/drupal-8.6.0.bare.testing.php.gz
core/modules/system/tests/fixtures/update/drupal-8.6.0-minimal-with-warm-caches.sql.gz
core/modules/system/tests/fixtures/update/drupal-8.bare.standard.php.gz
core/modules/system/tests/fixtures/update/drupal-8.filled.standard.php.gz
core/modules/system/tests/fixtures/update/drupal-8-rc1.bare.standard.php.gz
core/modules/system/tests/fixtures/update/drupal-8-rc1.filled.standard.php.gz

After discussing with @larowlan in going to create following dumps
8.8.0.bare.standard, 8.8.0.filled.standard, 8.8.0.bare.testing, 8.8.0.bare.minimal-with-warm-caches
Please let me know if we that is enough or not enough.

amateescu’s picture

I don't think 8.8.0.bare.minimal-with-warm-caches (or any dump with warm caches for that matter) is relevant anymore after #3055443: Switch to a null backend for all caches for running the database updates.

jibran’s picture

Thanks, I'll remove it.

jibran’s picture

Assigned: jibran » Unassigned
Status: Active » Needs review
FileSize
1.08 KB
9.57 KB
772.41 KB

Here is the patch which adds three more DB dumps 8.8.0.bare.standard, 8.8.0.filled.standard, and 8.8.0.bare.testing after running updates on exiting ones.

I hacked \Drupal\FunctionalTests\Update\UpdatePathTestBaseTest and \Drupal\Tests\system\Functional\Update\UpdatePathTestBaseFilledTest to use new core/modules/system/tests/fixtures/update/drupal-8.8.0.bare.standard.php.gz and core/modules/system/tests/fixtures/update/drupal-8.8.0.bare.standard.php.gz and they are passing now. Should we add new 8.8 only tests?

I have also added core/modules/system/tests/fixtures/update/drupal-8.8.0.bare.testing.php.gz but I'm not sure what type of test is best suited for this.

Do not test patch is contains all the code changes.
Also, uploading update-db-dump.txt which I used to generate the new dumps for the old dump.

Status: Needs review » Needs work

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

jibran’s picture

Left the existing tests alone and copied them to new one also added test for testing db dump.

Status: Needs review » Needs work

The last submitted patch, 13: 3089900-13.patch, failed testing. View results

catch’s picture

Status: Needs work » Needs review

HEAD was broken.

catch’s picture

#13 looks like a good start to me.

I'm not sure we can add a lot more coverage here because we have no specific updates to test yet, but we're bound to have a config update or similar to commit for 8.9.x soon, so I think it would make sense to start adding test coverage against these new databases instead of the old ones, to reduce conflicts with 9.x once we remove the old dumps.

+    // Ensure that all {router} entries can be unserialized. If they cannot be
+    // unserialized a notice will be thrown by PHP.
+
+    $result = \Drupal::database()->query("SELECT name, route from {router}")->fetchAllKeyed(0, 1);
+    // For the purpose of fetching the notices and displaying more helpful error
+    // messages, let's override the error handler temporarily.
+    set_error_handler(function ($severity, $message, $filename, $lineno) {
+      throw new \ErrorException($message, 0, $severity, $filename, $lineno);
+    });
+    foreach ($result as $route_name => $route) {
+      try {
+        unserialize($route);
+      }
+      catch (\Exception $e) {
+        $this->fail(sprintf('Error "%s" while unserializing route %s', $e->getMessage(), Html::escape($route_name)));
+      }
+    }
+    restore_error_handler();

This is for an older version update so it should never be possible to run into any more, but on the other hand it's test coverage for a hypothetical future problem with router entries so might as well leave it in?

jibran’s picture

I'm not sure we can add a lot more coverage here because we have no specific updates to test yet,

We are checking bare minimum here in my opinion which should be fine for the scope of this issue.

it's test coverage for a hypothetical future problem with router entries so might as well leave it in?

Given that #3087644: Remove Drupal 8 updates up to and including 88** is going to remove the old tests I'd say let's keep it.

Is anything left here to address?

catch’s picture

Status: Needs review » Reviewed & tested by the community
Issue tags: +D8 upgrade path

I don't think so, let's try to get some more reviews.

alexpott’s picture

Status: Reviewed & tested by the community » Needs work

I think it is okay to change the dumps that core/tests/Drupal/FunctionalTests/Update/UpdatePathTestBaseTest.php and core/modules/system/tests/src/Functional/Update/UpdatePathTestBaseFilledTest.php use so we don't have to delete them in 9.0.x.

These tests test update functionality not the dumps or specific updates.

Also I don't understand why the patch is adding both core/modules/system/tests/src/Functional/Update/UpdatePathTestBase88BareTest.php and core/tests/Drupal/FunctionalTests/Update/UpdatePathTestBase88Test.php - ah I guess this is to test both core/modules/system/tests/fixtures/update/drupal-8.8.0.bare.testing.php.gz and core/modules/system/tests/fixtures/update/drupal-8.8.0.bare.standard.php.gz. I think we shouldn't add core/modules/system/tests/fixtures/update/drupal-8.8.0.bare.testing.php.gz here. We've only used 4 times since it was added. I think testing updates with as many modules and other updates happening is a good thing. Side effects and unexpected results here are common (unfortunately).

alexpott’s picture

What I'm trying to say in #19 is that we should change \Drupal\FunctionalTests\Update\UpdatePathTestBaseTest and \Drupal\Tests\system\Functional\Update\UpdatePathTestBaseFilledTest to use the new 8.8 dumps rather than duplicating them.

jibran’s picture

Status: Needs review » Needs work

The last submitted patch, 21: 3089900-21.patch, failed testing. View results

jibran’s picture

We don't need core/modules/system/tests/src/Functional/Update/UpdateSchemaTest.php anymore.

alexpott’s picture

Here's the smallest possible change here. Which is what I think we want in order to preserve BC. So this patch does not change the user 1 account of the filled db. It also doesn't unnecessarily change the update numbers of the test module or remove any other tests.

alexpott’s picture

I've rebuilt the db dumps from the original 8.0.0 dumps because I can't explain how user 1 had their name and password by the process in #11.

My process is this:

  1. gunzip the dump (ie. gunzip -c core/modules/system/tests/fixtures/update/drupal-8.bare.standard.php.gz > drupal-8.bare.standard.php
  2. drop the entire site db. (ie. mysql -e "drop database drupal8alt; create database drupal8alt;"
  3. load the db (ie. drush src drupal-8.bare.standard.php
  4. run updates when on 8.8.x (ie. drush updb -y)
  5. dump db (ie. php core/scripts/dump-database-d8-mysql.php > drupal-8.8.0.bare.standard.php
  6. gzip drupal-8.8.0.bare.standard.php and copy it to the correct location
alexpott’s picture

+++ b/core/tests/Drupal/FunctionalTests/Update/UpdatePathTestBaseTest.php
@@ -37,8 +38,8 @@ public function testDatabaseLoaded() {
-    foreach (['user', 'node', 'system', 'update_test_schema'] as $module) {
-      $this->assertEqual(drupal_get_installed_schema_version($module), 8000, new FormattableMarkup('Module @module schema is 8000', ['@module' => $module]));
+    foreach (['user' => 8100, 'node' => 8700, 'system' => 8805, 'update_test_schema' => 8000] as $module => $schema) {
+      $this->assertEqual(drupal_get_installed_schema_version($module), $schema, new FormattableMarkup('Module @module schema is @schema', ['@module' => $module, '@schema' => $schema]));
     }

This change to the test is useful because it proves we're starting from a 8.8.x dump.

The last submitted patch, 24: 3089900-to-review-24.patch, failed testing. View results

alexpott’s picture

As per @amateescu we should drop the old_ tables from entity updates because they are not part of the update.

catch’s picture

Current patch I agree is the smallest change, I'm wondering about this change that was dropped:

+++ b/core/modules/system/tests/modules/update_test_schema/update_test_schema.install
@@ -53,12 +53,12 @@ function update_test_schema_schema() {
 // Update hooks are defined depending on state as well.
 $schema_version = \Drupal::state()->get('update_test_schema_version', 8000);
 
-if ($schema_version >= 8001) {
+if ($schema_version >= 8801) {
 
   /**
-   * Schema version 8001.
+   * Schema version 8801.
    */
-  function update_test_schema_update_8001() {
+  function update_test_schema_update_8801() {
     $table = [

On the one hand if this was an actual core module, it should only have updates 88** and above due to convention. On the other hand our actual update API will run updates from 8001 upwards. So... I actually think we should leave that hunk out too and the current patch is good.

alexpott’s picture

@catch yep that was my thinking too. Also if there's no change in this module and in the unlikely case some contrib or custom is using this module for very interesting update testing then at least this change won't break their testing.

Berdir’s picture

catch’s picture

Status: Needs review » Reviewed & tested by the community

OK I think this is RTBC with that follow-up opened.

Berdir’s picture

Status: Reviewed & tested by the community » Needs work
+++ b/core/tests/Drupal/FunctionalTests/Update/UpdatePathTestBaseTest.php
@@ -112,15 +113,11 @@ public function testUpdateHookN() {
   public function testPathAliasProcessing() {
     // Add a path alias for the '/admin' system path.
-    $database = \Drupal::database();
-    $database->insert('url_alias')
-      ->fields(['source', 'alias', 'langcode'])
-      ->values([
-        'source' => '/admin/structure',
-        'alias' => '/admin-structure-alias',
-        'langcode' => 'und',
-      ])
-      ->execute();
+    PathAlias::create([
+      'path' => '/admin/structure',
+      'alias' => '/admin-structure-alias',
+      'langcode' => 'und',
+    ])->save();
 

Using the entity API before running updates is a problem. It works now, but it will sooner or later break when we e.g. add another field to it.

It's ugly, but we should do this with raw database queries.

jibran’s picture

Assigned: Unassigned » jibran

Why not a new db script instead?

Berdir’s picture

+++ b/core/tests/Drupal/FunctionalTests/Update/UpdatePathTestBaseTest.php
@@ -113,14 +114,27 @@ public function testUpdateHookN() {
+    $revision_table_insert = $database->insert('path_alias_revision');
+    $revision_table_insert->fields(['id', 'revision_id', 'path', 'alias', 'langcode', 'status', 'revision_default']);
+    $values = [
+      'id' => 1,
+      'revision_id' => 1,
+      'uuid' => \Drupal::service('uuid'),
+      'path' => '/admin/structure',
+      'alias' => '/admin-structure-alias',
+      'langcode' => 'und',
+      'status' => 1,
+    ];
+    $base_table_insert->values($values);

service('uuid') gives you the uuid service, not a uuid ;)

This is also quite hard to understand IMHO. I don't think you need fields() at all when you provide values like this. Maybe define $values first for the shared ones, and then do $database->insert()->values($values + specific ones)->execute() twice, instead of building the queries in parallel?

jibran’s picture

Thanks, for the feedback.
\Drupal::service('uuid') was wrong copy paste.

jibran’s picture

FileSize
1.73 KB
714.2 KB

Ignore #37 this patch addresses #36 properly. Interdiff is from #35.

The last submitted patch, 35: 3089900-35.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

Berdir’s picture

Status: Needs review » Reviewed & tested by the community

Yeah, that's much more readable, RTBC if it passes. I didn't look into the database dumps, but @alexpott and @jibran have cross-reviewed and compared that *a lot*.

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 38: 3089900-38.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

jibran’s picture

Status: Needs work » Needs review
FileSize
1.35 KB
714.32 KB

Fixed the last fails.

Berdir’s picture

Status: Needs review » Reviewed & tested by the community

Now it passed :)

jibran’s picture

Just for clarity. Here are two DB diffs.

git diff --no-index -- core/modules/system/tests/fixtures/update/drupal-8.bare.standard.php core/modules/system/tests/fixtures/update/drupal-8.8.0.bare.standard.php > bare-db-8-to-8.8.x.diff

git diff --binary --no-index -- core/modules/system/tests/fixtures/update/drupal-8.filled.standard.php core/modules/system/tests/fixtures/update/drupal-8.8.0.filled.standard.php > filled-db-8-to-8.8.x.diff

  • catch committed c2e3f0b on 9.0.x
    Issue #3089900 by jibran, alexpott, catch, Berdir, amateescu: Drupal 8.8...

  • catch committed e7e8017 on 8.9.x
    Issue #3089900 by jibran, alexpott, catch, Berdir, amateescu: Drupal 8.8...

  • catch committed ef54880 on 8.8.x
    Issue #3089900 by jibran, alexpott, catch, Berdir, amateescu: Drupal 8.8...
catch’s picture

Version: 8.9.x-dev » 8.8.x-dev
Issue summary: View changes
Status: Reviewed & tested by the community » Fixed
Issue tags: +8.8.0 release notes, +9.0.0 release notes

Committed/pushed to 9.0.x, 8.9.x and 8.8.x, thanks!

Also tagging for both 8.8.0 and 9.9.0 release notes since this is a test harness addition that contrib can rely on too. Don't think it needs a change notice since no API has been changed or anything.

Status: Fixed » Closed (fixed)

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

xjm’s picture

Issue tags: -9.0.0 release notes

There's a CR for these changes at: https://www.drupal.org/node/3098322

@catch and I agreed this doesn't need to be mentioned in the release notes for D9.