Problem/Motivation

The current automated test results show 2 new failures.

One or more failures may result from changes introduced to core in #2915414: Omit "_core" key from normalized config entities, which includes the default config hash and/or other changes to core.

Proposed resolution

Remaining tasks

User interface changes

API changes

Data model changes

CommentFileSizeAuthor
#11 2990516-try-this.patch1.55 KBjhodgdon

Comments

nedjo created an issue. See original summary.

nedjo’s picture

While the test results show errors only for Config_update.Drupal\Tests\config_update_ui\Functional\ConfigUpdateTest, IIRC locally I got a failure for a 2nd test class in config_update_ui, ConfigProfileOverridesTest.

jhodgdon’s picture

Could be that is the change in Core... I'm not sure though.

The test that is failing is verifying that when we revert a config item, then go to the single export page, we retain the UUID and _core / default_config_hash lines.

The test is failing to see the default_config_hash line.

There could be two reasons for this:

a) When we revert, we aren't getting the default_config_hash item into the config any more for some reason (like maybe it's getting removed during config save?).

b) When Core exports config on the single export page, it is no longer including the _core section.

It seems to me we need to figure out which one is the reason. If it's (b), then we should change our test in that section so that we don't rely on the single export page to test whether the config contains the lines we are looking for. If it's (a), then we need to figure out whether it's a bug or not, and either change the test or fix the bug. So the next step would be, I think, to investigate whether Core is still using default_config_hash at all, and if so, whether it's still being exported on the single export page.

nedjo’s picture

There could be two reasons for this:

a) When we revert, we aren't getting the default_config_hash item into the config any more for some reason (like maybe it's getting removed during config save?).

b) When Core exports config on the single export page, it is no longer including the _core section.

I started with b). Steps:

Install core 8.7.x with the 'standard' install profile.
Log in, navigate to /admin/config/development/configuration/single/export, and export "contact.settings" of type "Simple configuration". Result:

default_form: feedback
flood:
  limit: 5
  interval: 3600
user_default_enabled: true
_core:
  default_config_hash: U69DBeuvXuNVOC15rVNaBjDPK2fWFbo9v4takdYSSO8

Implication: b) is not true.

Next looking at a). As a start, what are we doing to revert and what if anything has changed in the core code we're calling?

The test line we're getting this on relates to a config entity rather than simple configuration.

In ConfigReverter::revert() the relevant lines look to be these:

      // Load the current config entity and replace the value. Note that
      // the uuid and _core/hash values are retained for entity-based config,
      // since updateFromStorageRecord() only updates values that are part of
      // the passed-in array, and doesn't remove or alter other values.
      $definition = $this->entityManager->getDefinition($type);
      $id_key = $definition->getKey('id');
      $id = $value[$id_key];
      $entity_storage = $this->entityManager->getStorage($type);
      $entity = $entity_storage->load($id);
      $entity = $entity_storage->updateFromStorageRecord($entity, $value);
      $entity->save();

One possible place to look would be the relevant ::updateFromStorageRecord() method.

Looking at the most recent changes in what looks to be the relevant file:

$ git log core/lib/Drupal/Core/Config/Entity/ConfigEntityStorage.php

commit f28f56207da4ea7db575cdf766039f872fe56f84
Author: Nathaniel Catchpole
Date: Fri Jul 20 19:38:39 2018 +0100

Issue #2986901 by gabesullice, alexpott: Followup for #2666392: ConfigEntityTypeInterface::getPropertiesToExport no longer returns NULL, throws exception instead

(cherry picked from commit e6cf8fca136ae893c0df7de3b00a85eef3094cfe)

commit b55ed6bd46f0dd189c25cbd842ac9495baf41d67
Author: Nathaniel Catchpole
Date: Fri Jul 13 14:11:18 2018 +0100

Issue #2666392 by alexpott, webflo, xaqrox, Boobaa, dawehner, Berdir: Unable to revert third party settings via config import

Our first test failures seem to be from after that earlier date (July 13, 2018).

Looking to the specific commit and file:

git show b55ed6bd46f core/lib/Drupal/Core/Config/Entity/ConfigEntityStorage.phpcommit b55ed6bd46f0dd189c25cbd842ac9495baf41d67
Author: Nathaniel Catchpole <catch@35733.no-reply.drupal.org>
Date:   Fri Jul 13 14:11:18 2018 +0100

    Issue #2666392 by alexpott, webflo, xaqrox, Boobaa, dawehner, Berdir: Unable to revert third party settings via config import

diff --git a/core/lib/Drupal/Core/Config/Entity/ConfigEntityStorage.php b/core/lib/Drupal/Core/Config/Entity/ConfigEntityStorage.php
index 3b90899..e3d38d1 100644
--- a/core/lib/Drupal/Core/Config/Entity/ConfigEntityStorage.php
+++ b/core/lib/Drupal/Core/Config/Entity/ConfigEntityStorage.php
@@ -450,9 +450,19 @@ public function updateFromStorageRecord(ConfigEntityInterface $entity, array $va
     $data = $this->mapFromStorageRecords([$values]);
     $updated_entity = current($data);
 
-    foreach (array_keys($values) as $property) {
-      $value = $updated_entity->get($property);
-      $entity->set($property, $value);
+    /** @var \Drupal\Core\Config\Entity\ConfigEntityTypeInterface $entity_type */
+    $entity_type = $this->getEntityType();
+    $id_key = $entity_type->getKey('id');
+    foreach ($entity_type->getPropertiesToExport($updated_entity->get($id_key)) as $property) {
+      if ($property === $this->uuidKey) {
+        // During an update the UUID field should not be copied. Under regular
+        // circumstances the values will be equal. If configuration is written
+        // twice during configuration install the updated entity will not have a
+        // UUID.
+        // @see \Drupal\Core\Config\ConfigInstaller::createConfiguration()
+        continue;
+      }
+      $entity->set($property, $updated_entity->get($property));
     }

So, there have been changes in the method we're calling--but whether that's related or not remains TBD.

jhodgdon’s picture

Good detective work! That does indeed look like the change in Core that caused this test failure.

So. For non-entity config, we are specifically in the ConfigReverter::revert() method saving the old value of __core and putting it back after we copy in the new config values:

    if ($type == 'system.simple') {
      // Load the current config and replace the value, retaining the config
      // hash (which is part of the _core config key's value).
      $config = $this->configFactory->getEditable($full_name);
      $core = $config->get('_core');
      $config
        ->setData($value)
        ->set('_core', $core)
        ->save();
    }

That comment you referenced says that in contrast, we don't have to do that for entities, because updateFromStorageRecord *used to* not mess with __core. As of the commit above, this function now does mess with __core. So I think we need to just add a few lines to the method so that we save/replace __core just like we are doing for simple config.

Right?

jhodgdon’s picture

The other thing we could do is reopen that issue and complain that their commit broke our module, by changing the behavior of a public method. That I think would be valid.

nedjo’s picture

@jhodgdon That all sounds right, but I'm not following the code well enough to be certain of this part:

As of the commit above, this function now does mess with __core.

The revised code calls ConfigEntityType::getPropertiesToExport(), and that at least under certain conditions includes '_core' among the listed properties.

jhodgdon’s picture

Well it looks like we need to not assume that this Core function/class we are using will preserve __core, and so we should preserve it ourselves to maintain backwards compatibility, as we are doing for simple config.

nedjo’s picture

That sounds right.

Note: I jumped into looking at the code. I haven't yet tested to confirm I can reproduce what I'm assuming is the bug--that when we revert a config entity, we lose the _core property.

jhodgdon’s picture

Status: Active » Needs review
StatusFileSize
new1.55 KB

I got an email today from the Drupal Core dev team -- maybe you got it too? -- about being an 8.x contrib module maintainer saying to test modules against 8.x and file issues if there are compatibility issues, using particular tags... so I added a tag and comment to #2986901-14: Followup for #2666392: ConfigEntityTypeInterface::getPropertiesToExport no longer returns NULL, throws exception instead, and filed a new Core issue #2993876: Change notice or revert needed for #2986901.

In the meantime, we should probably assume Core isn't going to revert that change and continue with our work-around. Here's a proposed patch, which I haven't tested at all... it might work? Anyway I think we need to do something like this.

jhodgdon’s picture

That patch does seem to work. Thoughts?

nedjo’s picture

Status: Needs review » Reviewed & tested by the community

Yep, thanks for fixing this, good to go. I added a test with core 8.5 and that passed too.

  • jhodgdon committed 944b588 on 8.x-1.x
    Issue #2990516 by jhodgdon, nedjo: Address test failures due presumably...
jhodgdon’s picture

Status: Reviewed & tested by the community » Fixed

Thanks for reviewing! Committed.

Status: Fixed » Closed (fixed)

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