Provide guidance to config schema developers: detect broken config schema types

Created on 15 November 2023, about 1 year ago
Updated 28 March 2024, 9 months ago

Problem/Motivation

While working on πŸ“Œ Configuration schema & required keys Fixed and many other "config schema validation"-related issues, I've encountered a number of bugs in Drupal core's config schema.

The latest one is

filter_settings.filter_html:
  type: filter
…

which makes no sense because:

# Filter with module and status.
filter:
  type: mapping
  label: 'Filter'
  mapping:
    id:
      type: string
      label: 'ID'
    provider:
      type: string
      label: 'Provider'
    status:
      type: boolean
      label: 'Status'
    weight:
      type: integer
      label: 'Weight'
    settings:
      type: filter_settings.[%parent.id]

See how at the very end of that definition, there's type: filter_settings.[%parent.id]. So this is essentially a circular schema definition πŸ˜…

This is a bug that went unnoticed for almost a decade β†’ . It's becoming apparent now that we're starting to use more of the pre-existing config schema for richer validation.

πŸ‘† This was fixed in πŸ› Filter settings schema types are incorrect Active .

This issue uncovered one more occurrence of a circular config schema type reference, in type: layout_builder.section. See #21 for details.

Steps to reproduce

N/A

Proposed resolution

Add basic validation to config schema definitions: verify

  1. that the type is valid
  2. that there's no circular reference

Remaining tasks

  • βœ…
  • βœ…

User interface changes

None.

API changes

API addition: Extension::getAbsolutePath() β€” change record β†’

Data model changes

None.

Release notes snippet

None.

πŸ“Œ Task
Status

Needs work

Version

11.0 πŸ”₯

Component
ConfigurationΒ  β†’

Last updated 3 days ago

Created by

πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

Live updates comments and jobs are added and updated live.
  • Needs subsystem maintainer review

    It is used to alert the maintainer(s) of a particular core subsystem that an issue significantly impacts their subsystem, and their signoff is needed (see the governance policy draft for more information). Also, if you use this tag, make sure the issue component is set to the correct subsystem. If an issue significantly impacts more than one subsystem, use needs framework manager review instead.

Sign in to follow issues

Merge Requests

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • Issue created by @wim leers
  • Issue was unassigned.
  • Status changed to Needs review about 1 year ago
  • πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί
  • Pipeline finished with Failed
    about 1 year ago
    Total: 608s
    #50085
  • πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

    LOTS of failures like this:

    Drupal\Tests\history\Kernel\Views\HistoryTimestampTest::testHandlers
    LogicException: Config schema type "filter_settings.filter_html" has a circular type reference, where it uses the type "filter_settings.[%parent.id]".

    πŸ‘

  • Pipeline finished with Success
    about 1 year ago
    Total: 813s
    #50100
  • πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

    The code needs refining, but I'd first like feedback from a subsystem maintainer before spending many more hours on this (this already took me 2–3 hours).

    I would like an explicit +1 that this change would be welcomed.

  • πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί
  • πŸ‡§πŸ‡ͺBelgium borisson_ Mechelen, πŸ‡§πŸ‡ͺ

    I'm not a subsystem maintainer, but I like this - it would make schema definitions more robust. I wonder if this is something that we need to add to TypedConfigManager, or somewhere else, but that is an implementation detail.

  • πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

    I wonder if this is something that we need to add to TypedConfigManager, or somewhere else,

    What would the other possible location be? πŸ€”

    Maybe the config.storage.schema service, which is used by TypedConfigManager? That would force it to happen at a lower level/earlier time, which may be better?

  • Status changed to Needs work about 1 year ago
  • πŸ‡ΊπŸ‡ΈUnited States phenaproxima Massachusetts
  • Status changed to Needs review about 1 year ago
  • πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

    See #5.

  • Status changed to Needs work about 1 year ago
  • Status changed to Needs review about 1 year ago
  • First commit to issue fork.
  • πŸ‡·πŸ‡ΊRussia kostyashupenko Omsk

    I don't think we need to add this tag. It just meant MR needs rebase and rebase is done

  • Pipeline finished with Failed
    about 1 year ago
    Total: 1150s
    #56586
  • πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

    @kostyashupenko I know. But the point is that this MR should NOT chase HEAD. See #10 and #5.

    Thanks for the rebase though! :D

    P.S.: another issue relating to the poor config schema DX today: πŸ“Œ [PP-1] Validate inputs of config schema's TypeResolver: only allow %parent, %type and %key Postponed .

  • πŸ‡§πŸ‡ͺBelgium borisson_ Mechelen, πŸ‡§πŸ‡ͺ

    #8, it has taken me a while to get back to this, I have though this trough, I really wanted to suggest to put the validation of the schema in a new service/class, but I think it makes most sense to put it here, where we are adding a lot of the other validation passes as well.

  • πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

    FYI the actual fixes that this MR makes are also in πŸ› Filter settings schema types are incorrect Active . This issue aims to add infrastructure to prevent similar problems.

  • Status changed to Needs work 11 months ago
  • πŸ‡ΊπŸ‡ΈUnited States smustgrave

    Not sure if still needs subsystem review.

    But MR appears to be unmergable.

  • Assigned to wim leers
  • πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί
  • Pipeline finished with Failed
    11 months ago
    #87799
  • Pipeline finished with Failed
    11 months ago
    Total: 927s
    #87802
  • Pipeline finished with Failed
    11 months ago
    #87815
  • Pipeline finished with Failed
    11 months ago
    Total: 844s
    #87838
  • Pipeline finished with Failed
    11 months ago
    Total: 682s
    #87846
  • Pipeline finished with Success
    11 months ago
    Total: 539s
    #87891
  • Pipeline finished with Success
    11 months ago
    Total: 481s
    #87914
  • πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

    All feedback except one piece has been addressed, and tests are now passing!

    Moving on to the last piece of feedback… which is also the only @todo I had added πŸ‘

  • Pipeline finished with Failed
    11 months ago
    Total: 530s
    #87931
  • Issue was unassigned.
  • Status changed to Needs review 11 months ago
  • πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

    The last piece of feedback/the @todo I had added was to not just run this validation for the filter_settings.filter_html config schema type, but for ALL config schema types.

    Doing this seemed to work fine locally, but caused 254 test failures on GitLab CI. They all look like this:

    LogicException: Config schema type "core.entity_view_display.*.*.*.third_party.layout_builder" has a circular type reference, where it uses the type "[%parent.%parent.%type].third_party.[%key]".
    

    Turns out that #2942661: Sections should have third-party settings β†’ introduced the ability to define third party settings on Layout Builder Sections. So the layout_builder.section type got this addition:

        third_party_settings:
          type: sequence
          label: 'Third party settings'
          sequence:
            type: '[%parent.%parent.%type].third_party.[%key]'
    

    (Copy/pasted from type: config_entity.) But this is wrong; it should have used the same pattern as for example field formatter settings (which are stored in EntityViewDisplay config entities aka core.entity_view_display.*.*.*) getting third party settings; they used type: field.formatter.third_party.[%key]. Similarly, here we needed:

            type: 'layout_builder.section.third_party.[%key]'
    

    Why is this necessary? Because:

    1. Layout Builder stores its settings as third party settings on Entity View Displays, at core.entity_view_display.*.*.*.third_party.layout_builder", which is only one of many possible third party settings on entity view display config entities β€” all config entities allow arbitrary third party settings using [%parent.%parent.%type].third_party.[%key]
    2. That is a mapping containing a sections key that is a list of Layout Builder Sections (i.e. layout_builder.section)
    3. And because #2942661 added third party settings to type: layout_builder.section using that same [%parent.%parent.%type].third_party.[%key], the grandparent/two levels up (%parent.%parent) does not refer to the root of the config entity and uses its type (core.entity_view_display.*.*.*), but instead it refers to … layout_builder.section itself! πŸ‘ˆ this is the circular reference! ⚠️

    Next up: test coverage. This needs test coverage using a pattern similar to the one in \Drupal\KernelTests\Config\Schema\MappingTest::testInvalidMappingKeyDefinition().

  • Pipeline finished with Success
    11 months ago
    Total: 582s
    #87967
  • Pipeline finished with Canceled
    11 months ago
    Total: 2191s
    #87955
  • Pipeline finished with Success
    11 months ago
    Total: 592s
    #87981
  • Pipeline finished with Success
    11 months ago
    Total: 783s
    #88005
  • Assigned to wim leers
  • πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

    Tried to write tests.

    The more representative test coverage pattern to copy is actually \Drupal\Tests\ckeditor5\Kernel\CKEditor5PluginManagerTest::testInvalidPluginDefinitions().

    Writing test coverage for this is very complicated because of the hardcoded assumptions in ExtensionDiscovery. See \Drupal\Tests\ckeditor5\Kernel\CKEditor5PluginManagerTest::mockModuleInVfs(), where I previously had to deal with this. 😬 To be continued tomorrow.

  • Pipeline finished with Success
    11 months ago
    Total: 556s
    #88049
  • Issue was unassigned.
  • Status changed to Needs work 11 months ago
  • πŸ‡ΊπŸ‡ΈUnited States phenaproxima Massachusetts

    This is making more and more sense.

    It's extremely complicated logic, and very obscure (as the config schema system tends to be). I'm wondering if we can change the comments/method names in some places to make it as clear as possible to future developers who need to try and come to grips with this stuff.

    But the logic itself, I don't have any real complaints about.

  • Assigned to phenaproxima
  • Status changed to Needs review 11 months ago
  • πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

    πŸ“

    It's very obscure, complicated logic

    It's not obscure, but it is complicated. To understand the logic, you have to understand how config schema type definitions. Once you understand that, it should no longer be obscure. And in fact, this logic should help make config schema in general less obscure for the next person πŸ˜…

  • πŸ‡ΊπŸ‡ΈUnited States phenaproxima Massachusetts

    Hopefully I didn't hit a nerve :) I meant it's obscure because config schema itself is kind of obscure. Hopefully as it becomes more "useful" (and consistent!) thanks to this work, the obscurity will disappear.

  • Assigned to wim leers
  • Status changed to Needs work 11 months ago
  • πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

    Hahaha, not at all β€” no worries! πŸ˜„ What you're saying in #25 is the same as what I said in #24. We agree that knowledge about the config schema system is obscure (hard-won) knowledge, that we're trying to make more accessible in this issue by removing some of it πŸ‘

  • Pipeline finished with Success
    11 months ago
    Total: 586s
    #88740
  • Pipeline finished with Success
    11 months ago
    Total: 594s
    #88778
  • πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

    The tests were hard to write β€” I was able to copy most of the pattern in \Drupal\Tests\ckeditor5\Kernel\CKEditor5PluginManagerTest::mockModuleInVfs() but not everything. Which also led me to push #2961541 forward again β€” see #2961541-26: ExtensionDiscovery fails to scan the vfsStream filesystem for modules or profiles β†’ .

  • Issue was unassigned.
  • Status changed to Needs review 11 months ago
  • πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

    All feedback addressed πŸ‘

  • πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί
  • Pipeline finished with Success
    11 months ago
    Total: 584s
    #88819
  • πŸ‡ΊπŸ‡ΈUnited States phenaproxima Massachusetts

    A couple of questions but I don't think I have any problems with this in general.

    Although I think I understand the code here, I'm not really comfortable RTBCing it; it needs subsystem maintainer review anyway, so that's probably who should give it the green light.

  • Assigned to phenaproxima
  • πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

    Remaining feedback addressed!

    @phenaproxima I'm hoping you can close 3 of the 4 threads πŸ™ (one is a committer FYI and can remain open)

  • Pipeline finished with Success
    11 months ago
    Total: 592s
    #89493
  • πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

    Addressed @alexpott's MR feedback. That resulted in an API addition (Extension::getAbsolutePath()) and a change record: https://www.drupal.org/node/3420082 β†’ .

  • Pipeline finished with Success
    10 months ago
    Total: 485s
    #90505
  • Issue was unassigned.
  • πŸ‡ΊπŸ‡ΈUnited States phenaproxima Massachusetts

    I'm out of complaints here.

    I think someone else should give the official RTBC since I'm not an expert in the subject matter. But as far as I can tell, this is RTBC.

  • Assigned to wim leers
  • Status changed to Needs work 10 months ago
  • πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί
  • Issue was unassigned.
  • πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

    πŸ“Œ [PP-1] Validate inputs of config schema's TypeResolver: only allow %parent, %type and %key Postponed landed!

    I won't have time for this soon though … so unassigning.

Production build 0.71.5 2024