Problem/Motivation
#2245729: Add missing configuration schema in Color component introduced \Drupal\Core\Config\Schema\SchemaCheckTrait. That helped fix #2231059: [meta] Find out what config schemas are still missing and add them, together with #2183983: Find hidden configuration schema issues.
(Which BTW is where @Gábor Hojtsy's infamous Config Schema Cheat Sheet comes from: see #2183983-179: Find hidden configuration schema issues 😊.)
This was then moved out of a test-only context by #2625212: Add ConfigSchemaChecker to development.services.yml.
Since then, #2870878: Add config validation for UUIDs was the first config schema type to gain explicit validation support. The validation performed by SchemaCheckTrait is unfortunately very superficial: it only checks if the primitive type storage type is correct (e.g. string vs integer vs boolean).
Steps to reproduce
This is fortunately easy to prove:
media.settingshas aoembed_providers_urlkey-value pair. As the name suggests, it ought to contain a URL. The default value is'https://oembed.com/providers.json'.- Its config schema:
oembed_providers_url: type: uri label: 'The URL of the oEmbed providers database in JSON format' - Note the
type: uri. That type is defined incore.data_types.schema.yml:
uri: label: 'Uri' class: '\Drupal\Core\TypedData\Plugin\DataType\Uri' - Thanks to
\Drupal\Core\TypedData\TypedDataManager::getDefaultConstraints(), this has had a validation constraint since the very beginning:
// Auto-generate a constraint for data types implementing a primitive // interface. if (is_subclass_of($type_definition['class'], '\Drupal\Core\TypedData\PrimitiveInterface')) { $constraints['PrimitiveType'] = []; } - That means all
type: uridata is validated by\Drupal\Core\Validation\Plugin\Validation\Constraint\PrimitiveTypeConstraintValidator::validate(), and it sure has logic for this:
// Ensure that URIs comply with http://tools.ietf.org/html/rfc3986, which // requires: // - That it is well formed (parse_url() returns FALSE if not). // - That it contains a scheme (parse_url(, PHP_URL_SCHEME) returns NULL if // not). if ($typed_data instanceof UriInterface && in_array(parse_url($value, PHP_URL_SCHEME), [NULL, FALSE], TRUE)) { $valid = FALSE; } - 💡 So this means that a value such as
"https://oembed.com/providers.json"should be valid (and it is) and a value like"Ceci n'est pas une URL."should be invalid (and it is). Great! - ❌ EXCEPT … none of this validation logic actually runs!
In other words: the only validation that happens when doing so-called "strict" schema checking is whether the storage type is valid. Not a single validation constraint is executed, not even those for primitive types that have existed since day 1 (see #2002102: Move TypedData primitive types to interfaces). 🙈
Proposed resolution
- Make
\Drupal\KernelTests\KernelTestBase::$strictConfigSchemaalso execute validation constraints. - Fix any validation errors that this surfaces:
media.settings:iframe_domain(which istype: uri): the default value is''but that is not a valid URI. See #5 for the test failures.
👉 Solution: keep the same type but addnullable: true. Precedent for this exists ineditor.editor.*: image_upload.max_dimensions.width— introduced in 2016 in #2644838: Add test coverage for the editor's max dimension setting, and fix its message when one dimension is unrestricted. Did that in #8. This also requires a tweak to theMediaSettingsForm(#77.3 + #79).system.theme.global:logo.url(which is oftype: uri): same exact problem! Failures in #11, solution in #12. This does not require a form tweak, because no form modifies this — see #79.update.settings:fetch.url: same pattern again, failures in #14, solution in #16. This does not require a form tweak, because no form modifies this — see #79.
- To avoid this issue becoming enormous with hundreds of validation constraint violations to fix in various tests, this issue instead only fixes the primitive validation constraint violations that Drupal has been claiming to comply with all along, but which has not truly been the case. That means any validation constraint violations with the following messages are not treated as a test failure trigger:
$ignored_validation_constraint_messages = [ // @see \Drupal\Core\Config\Plugin\Validation\Constraint\ConfigExistsConstraint::$message // @todo Remove this in https://www.drupal.org/project/drupal/issues/3362453 "The '.*' config does not exist.", // @see \Drupal\Core\Extension\Plugin\Validation\Constraint\ExtensionExistsConstraint::$moduleMessage // @see \Drupal\Core\Extension\Plugin\Validation\Constraint\ExtensionExistsConstraint::$themeMessage // @todo Remove this in https://www.drupal.org/project/drupal/issues/3362456 "Module '.*' is not installed.", "Theme '.*' is not installed.", // @see \Drupal\Core\Plugin\Plugin\Validation\Constraint\PluginExistsConstraint::$unknownPluginMessage // @todo Remove this in https://www.drupal.org/project/drupal/issues/3362457 "The '.*' plugin does not exist.", // @see "machine_name" in core.data_types.schema.yml // @todo Remove this in https://www.drupal.org/project/drupal/issues/3372972 "The <em class=\"placeholder\">.*<\/em> machine name is not valid.", ];They each have follow-up issues already:
- #3362453: Fix all ConfigExists constraint violations in tests
- #3362456: Fix all ExtensionExistsConstraint constraint violations in tests
- #3362457: Fix all PluginExistsConstraint constraint violations in tests
- #3372972: Fix all type: machine_name constraint violations in tests
Note that the last of those is a tweaked validation constraint message for
type: machine_name'sRegExconstraint, because until now it was using the default message at\Drupal\Core\Validation\Plugin\Validation\Constraint\RegexConstraint::$message:'This value is not valid.'— which means that if we don't tweak it, there's no way for us to specifically detect that the occurrence of such a message is for atype: machine_namecase. Hence the only addition in this issue, is making the message more specific. Which is not a BC break, because #2920678: Add config validation for the allowed characters of machine names landed in10.2.x, not10.1.x. - 100% of the changes in existing tests are essential to keep tests passing: sometimes there was a problem in the data used in tests, sometimes tweaks were needed to test infrastructure.
- In about a dozen cases, a genuine bug was fixed, surfaced thanks to actually running validation constraints! 🥳
Remaining tasks
Discuss.Implement.Review.
User interface changes
None.
API changes
Strict config schema checking now also validates constraints, which means that many config schema checking is now actually becoming strict.
See #42 for the ecosystem (contrib/custom) impact of the current patch. If preferred, we could change it so that only core tests are affected, and for contrib we'd make config schema checks that fail only due to validation errors trigger deprecation errors instead.
Data model changes
- The config schema is broadened for
media.settings:iframe_domain,system.theme.global:logo.urlandupdate.settings:fetch.url: rather than only allowing strings shaped like URIs, it now also allows NULL. - The default config values for
media.settings:iframe_domain,system.theme.global:logo.urlandupdate.settings:fetch.urlare changed from the empty string ('') to NULL (~). hook_update_N()hook_post_update_NAME()implementations are present, including test coverage, since#37#75.
Release notes snippet
Kernel & Functional tests now perform stricter config schema validation, which may lead to discovering incorrect configuration was being used in some tests. Read the change record for a concrete example of how to update the tests and/or default configuration in your modules, as well as why this helps improve reliability of the Drupal ecosystem.
Important: only tests in Drupal core will trigger errors, tests for contrib or custom modules, themes, installation profiles and distributions will trigger deprecation notices instead.
| Comment | File | Size | Author |
|---|---|---|---|
| #83 | 3361534-83.patch | 41.67 KB | wim leers |
| #83 | interdiff.txt | 1.83 KB | wim leers |
| #79 | 3361534-79.patch | 39.84 KB | wim leers |
| #79 | interdiff.txt | 1.36 KB | wim leers |
| #78 | 3361534-77.patch | 39.27 KB | wim leers |
Comments
Comment #2
wim leersHere's a trivial patch that modifies
media.settings.ymlto haveI bet that this will still pass the core test suite.
(Except for maybe some functional test that depends on it? 🤔)
P.S.: yes, to be Belgian is to be surreal.
Comment #3
wim leersCeci c'est une patch.
Comment #4
wim leers… all it takes is a dash of additional test logic! 😊
Now we should see failures like:
… and ah, the
iframe_domainkey-value pair is also invalid in the defaultmedia.settings.yml! 😅Makes sense, because
iframe_domain: ''is not a valid URI, whereas the config schema dictates it should be:Comment #5
wim leers🫠 Thanks for killing my joke, DrupalCI! Redid them.
Comment #6
andypostIt's great catch! The added @todo needs link to issue where we can get rid of it
Comment #7
wim leersFix typo in IS — thanks @Gábor Hojtsy!
Comment #8
wim leersThe failures in #5 are hard failures because the errors occur so early:
This is hence causing widespread failures:
Now let's revert the silly changes to
media.settingsfor theoembed_providers_urlkey and instead fix the config schema foriframe_domainkey.Comment #10
wim leersThe test failure that isn't
That actually passed tests. The only failure is
Drupal\FunctionalTests\Installer\InstallerExistingConfigSyncDirectoryMultilingualTest::testConfigSync, which is a random (but frequent) failure in core since it updated to Symfony 6.3 — see #3361121: [random test failure] InstallerExistingConfig[SyncDirectory]MultilingualTest::testConfigSync.Next
Let's do this now… and find out what other default config in core does not match the config schema.
Comment #11
wim leersWrong patch. Here's the right one.
Comment #12
wim leersJust like #8 before, now that we're properly validating all config instead of just
media.settings, we've discovered new problems:Let's fix that too, just like we fixed
media.settings. 👍Comment #13
wim leersComment #14
wim leersMany more tests are passing, but I only updated the default config in
systemmodule. I also needed to update the profile-level overrides inminimalanddemo_umami.Comment #15
wim leersLots of failures (269 failures ⚠️) throughout now:
(thanks to #3324150: Add validation constraints to config_entity.dependencies)
(thanks to CKEditor 5 having detailed config validation already)
(thanks to #3324150: Add validation constraints to config_entity.dependencies)
and after fixing that
(thanks to #2920682: Add config validation for plugin IDs)
It's gonna be interesting to fix these … 😅 BUT!
This means that all the config validation work is starting to pay off! If we get this to green, then we'll be gradually making our tests more reliable and make our config more accurate!
Comment #16
wim leersAlphabetically solving these:
→ missing config
→ wrong config schema for
update.settings:fetch.url, same problem and solution asmedia.settings:iframe_domainandsystem.theme.global:logo.urlConfig schema fix rather than test fix ⇒ reuploading patch, since it is likely to fix many failures.
Comment #17
wim leersAlphabetically continuing:
→ incomplete block config
→ obscured by a functional test hitting a 500 error now ⇒ dump of the page shows:
→ use a block plugin that actually exists, such as
system_powered_by_blockinstead offoo→
core/modules/block_content/tests/modules/block_content_test/config/install/block.block.foobargorilla.ymlis referencing→ but that
block_contententity does not exist: we need to ensure it already exists. But … really there should have been a content dependency, which is possible since #2282519: Add content dependency information to configuration entities. Newer config exports likecore/profiles/demo_umami/config/optional/block.block.umami_banner_home.ymldo do this correctly. But … that has a whole lot of custom infrastructure (see\Drupal\demo_umami_content\InstallHelper::importContentFromFile()). Precisely because this is an unsolved problem, #3324150: Add validation constraints to config_entity.dependencies did not add validation constraints to content dependencies.→ Fixed by adding
block_content_test_module_preinstall()modeled after Umami's example.Test module fix rather than test fix ⇒ reuploading patch, since it's likely to fix multiple failures.
⚠️ But it's become pretty apparent that continuing this will result in one massive patch. So rather than continuing to fix all problems in all tests, let's specifically detect certain validation errors and ignore them, with each of them having a corresponding follow-up issue. That way, we can at least start stabilizing/improving things, beginning with complying with the primitive types :)
Comment #18
wim leersCorrect patch + interdiff. I was missing 2 hunks.
Comment #19
borisson_That will probably lead to a huge list of new issues, but hopefully they should all be super small and easy to land, is there a way we can group them by type, so that we don't have 250 new issues? I think it would be super fun to see
[PP-250]in this issue but that shouldn't be a reason to do that.Is postponing this issue on the new issues better/easier/faster to land than writing specific code here to only detect certain errors?
Comment #20
wim leers#16 did get it down from 269 to 223 failures! 🥳
#19: Definitely not 250 issues 🤪🤣. One issue per validation constraint IMHO. Because for each of them, the same handful of patterns of fixes should apply.
This refines the validation to exclude the failures for non-primitive validation constraints, and defers to follow-ups:
Let's see which others I need to exclude and create follow-up issues for… 🤞
Comment #21
wim leersinterdiff-revert.txtcore/modules/config/tests/config_test/config/install/config_test.validation.ymlis missing alangcodekey-value pair:interdiff-fix_config_test.txt.(Combined:
interdiff.txt.)It's already clear we're going to need more follow-up issues though. (#20 will finish running in ~30 mins.)
Comment #22
wim leers🥳
This should fix pretty much all failing update path tests, bringing it down to
5145 if I'm lucky!Comment #23
wim leersThis issue surfaced one genuine bug in the CKEditor 5 test coverage! 👍
Beyond that bugfix, we need to make some tweaks in the CKEditor 5's test coverage because
::assertConfigSchema()now does more.This will hopefully bring it down to ~20.
Will continue tomorrow.
Comment #24
wim leersphpcsviolation fixed. Plus one obvious bug in a test that causes a validation error now:0ain't a UUID!Comment #25
borisson_This looks great, It took me a while to fully understand this, but it looks like a solid implementation to allow us to fix the rest in followups
🥳
I don't think this is needed to keep in the comment, it is useful for this issue but not for the endresult imho
Should we open an issue for this todo as well? So that we know that this should be removed, because just the todo will not be enough I think.
Comment #26
wim leersThe default config for Umami Demo had CKEditor 5 validation constraint violations (which this issue's added infrastructure will forever prevent — we have special additional test coverage in Standard for exactly this, introduced in #3271097: Replace CKEditor 4 with CKEditor 5 in the Standard profile and StandardTest).
This should fix 2 failures and allow the
Nightwatchtest for Umami Demo to stop crashing, which is why d.o is not accurately reporting failures 🤪Comment #28
wim leers#26 brought it down from 21 to 17, and now the results actually show up! Which means Nightwatch tests are now indeed passing again. Will stop these recaps going forward 👍
Fix a bunch of
[dependencies.theme.0] This value should not be blank.errors, which is technically caused by #3324150: Add validation constraints to config_entity.dependencies, but it's really just a handful, so no point in creating a follow-up issue.That concludes all fixes for Block. Just leaves one for Views. Turns out that's just forgotten to inject the validation constraint manager into
TypedConfigManager— easy! 👍This should bring it down to 13 failures.
Comment #29
wim leers100% of the Layout Builder test failures are because the strings
first-uuidandsecond-uuidare used as if they are UUIDs. That's no longer accepted.Simple solution for that too: replace
first-uuidwith10000000-0000-0000-0000-000000000000, similar for the second one. But … turns out that UUID validation is strict by default, which imposes additional requirements … so had to go with10000000-0000-1000-a000-000000000000and20000000-0000-1000-a000-00000000000— which I think is equally simple. (And actually makes the tests clearer.)That should bring us down to <10 failures.
Comment #31
wim leersCKEditor5PluginManagerTestwas interesting:::setUp()caused the CKEditor 5 plugin manager that's available via a convenience property on the test class to become primed with information of the modules installed at the time that::setUp()runs. But many test methods on this test class enable additional modules to test additional edge cases. This was easily remedied, but was mystifying at first. Keeping references to services is always dangerous 🙈::testProvidedElements()now triggers additional validation (previously, only the config schema was asserted), and in doing so it was unveiled that theheading text container combotest case was not entirely accurate: even if testing the correctness of the text editor config entity was not the purpose of this test, that is now enforced even for this test. Which is why the default toolbar items (defined by\Drupal\ckeditor5\Plugin\Editor\CKEditor5::getDefaultSettings()) are inherited for all these tests. Which is why every test case was required to contain configuration for theckeditor5_headingplugin! Again, a simple tweak fixes it.Comment #32
wim leersPHPCS
Comment #34
wim leersTypedConfigTestwas trivial (It's intentionally making mistakes to test config schema validation)SchemaCheckTraitTestwas also trivial: one addition because now validation constraints are being checked.\Drupal\KernelTests\Core\Config\DefaultConfigTestis almost impossible to fix while keeping its current simplicity.The reason: its too simple:
This reads every piece of configuration in isolation, and asserts it conforms to the config schema. But … it does not import dependencies. It does not even install these modules.
IOW: it only checks conformity to the storage types. Which is exactly what this issue aims to change. And in doing so, we already found many bugs in config and tests in this issue.
DefaultConfigTestwas introduced in January 2014. 3 months later,\Drupal\Tests\config\Functional\ConfigImportAllTestwas added. Another 3 months later,use SchemaCheckTestTrait;was added toConfigImportAllTest. Since that moment,DefaultConfigTesthas basically been obsolete. It served its purpose!So I think the solution is clear: delete it. Otherwise we need to modify it to do almost the same as
ConfigImportAllTest!Patch should be green now!
Comment #36
wim leers#25 @borisson_ thanks for the review! 😊
$v->getMessage()😊Comment #37
wim leersWhile addressing #25.3, I realized:
media.settings,update.settingsandsystem.theme.globalin case they are still at their default valuesUpdatePathTestBase::$configSchemaCheckerExclusions(): with those update hooks in place, update tests won't fail anyway!Oops 😅
Comment #38
wim leersUpdated issue summary. This is now ready for final review.
Comment #39
wim leersPHPCS
Comment #40
wim leers@group media@group updateComment #41
borisson_I'm a bit unsure about the removal of \Drupal\KernelTests\Core\Config\DefaultConfigTest, but #34 explains why it was removed fairly well and when reading this it totally seems like a logical thing to do.
All the other changes are very simple and just get the configuration correct, so those are all very logical to me.
As mentioned in #19 I agree with there being 3 followups, luckily those are a lot fewer then I expected there to be because we can group the issues together.
I've read trough the patch a couple of times and there is nothing in there that I think needs to be changed, this is basically a test-only change that increases our strictness and validation coverage, so rtbc imho
Comment #42
wim leersThere is an ecosystem impact though!
Tests in contributed modules will start failing if they are using invalid configuration. Just like happened for Drupal core in this issue. But clearly, the number of config schema violations is very low. Still, that is some level of disruption.
So, updated issue summary and created a change record: https://www.drupal.org/node/3362879. I tried to make it as clear and helpfully concrete a change record as possible, but feedback welcome of course! 😊
There will be more failures once we start:
$ignored_validation_constraint_messagesin\Drupal\Core\Config\Schema\SchemaCheckTrait::checkConfigSchema()But all of those will be incremental improvements and will help increase the reliability of the entire Drupal ecosystem. In fact, it will even make update paths and migrations more reliable, because configuration integrity problems will be much more clear.
Comment #43
wim leersRerolled after conflicts with #3337513: Fix batch process race conditions by making ‘bid (batch id)’ auto-increment and #3360991: TypedData instances created by TypedConfigManager::createFromNameAndData() are incomplete.
Comment #44
catchAdding #3361423: [meta] Make config schema checking something that can be ignored when testing contrib modules as a related issue.
@lauriii suggested making this change early in 10.2.x which seems good, however I also think it would be good to try to get the above issue sorted, so that modules can enable/disable strict schema checking via DrupalCI's deprecation failure config rather than actual code changes to the tests.
Comment #45
wim leersI worked on ensuring that issue is sorted! 🤓😄
Comment #46
wim leers~1/3rd of this patch is for updating Layout Builder's tests. Splitting that off to a child issue: #3363873: Stop using `first-uuid` and `second-uuid` in tests: violates config schema.
Comment #47
lauriiiComment #48
wim leers#3363873: Stop using `first-uuid` and `second-uuid` in tests: violates config schema landed 🥳
From 48 KB in #43 to 34 KB now 👍
Comment #49
wim leersThe CKEditor 5 kernel test changes here are the most distracting/out-of-scope looking changes here. I think I can extract the trickiest pieces in a separate issue. Did that: #3364378: Tighten CKEditor 5 kernel tests.
Comment #50
longwaveNW to remove the @todos added in #3364378: Tighten CKEditor 5 kernel tests. Also the last CI run failed hard, not sure what happened there.
Comment #51
wim leers#3364378: Tighten CKEditor 5 kernel tests landed, rerolling #48.
Comment #52
wim leersI believe that the remaining patch now is much clearer in scope, should make it much more feasible for a core committer to feel confident when committing this 😊
P.S.: Regarding the last CI run failing hard: I bet it's because #2920678: Add config validation for the allowed characters of machine names landed.
Comment #53
wim leersYep, my P.S. in #52 was correct — e.g.
So this falls in the same category as #3362453: Fix all ConfigExists constraint violations in tests, #3362456: Fix all ExtensionExistsConstraint constraint violations in tests and #3362457: Fix all PluginExistsConstraint constraint violations in tests. Creating a follow-up for this one too.
But first, making that validation message much more helpful. Let's override
\Drupal\Core\Validation\Plugin\Validation\Constraint\RegexConstraint::$message's super unhelpful'This value is not valid.'message to something A) more specific, B) something that actually shows the value.Now we should see
Comment #54
wim leersOn second thought, I wonder if we don't need a follow-up but just need to tweak the regex for a few config entity types' machine names? Cases that were missed in #2920678: Add config validation for the allowed characters of machine names because they A) barely have test coverage, B) have no UI?
Let's find out!
Comment #56
wim leersAFAICT the #1 cause for failures are random machine names such as
rJuF3jOdthat are generated by\Drupal\TestTools\Random::machineName(), even though machine names are supposed to be all lowercase.So … just
strtolower()in that method should fix most failures?Comment #57
wim leersGreat, that
strtolower()fixed 64% of all failures. 👍Many (most?) of the remaining failures are just related to the fact that the existing config validation test coverage expects
Regex: "/some regex/", but in #53 I had to specify a custom validation constraint message to make the validation errors actually useful. We can choose to revert #53, or we can choose to refine\Drupal\KernelTests\Core\Config\ConfigEntityValidationTestBase::testInvalidMachineNameCharacters(), to expect the more helpful validation errors. I chose the latter.Comment #58
longwaveRe #56 see #2972573: randomMachineName() should conform to processMachineName() pattern
Comment #59
wim leersThat's largely green! 🤩
Failures:
BlockSystemBrandingTest+BlockTest+LanguageUILanguageNegotiationTest+LocaleConfigTranslationImportTest+ArgumentDefaultTestcreate test blocks with dashes in the ID instead of underscores. Easy fix!BlockContentWizardTesteven created a test block type with spaces in the ID 😅 Easy fix!\Drupal\Tests\jsonapi\Functional\ShortcutSetTest+ShortcutSetJsonAnonTest+ShortcutSetJsonBasicAuthTest+ShortcutSetJsonCookieTest+ShortcutSetXmlAnonTest+ShortcutSetXmlBasicAuthTest+ShortcutSetXmlCookieTestcreate a shortcut set with underscores instead of dashesTemporaryJsonapiFileFieldUploaderTestcreates a test role with spaces in the ID! 😳 Easy fix!NodeRevisionWizardTest: node types with dashes in the ID instead of underscoresArgumentDefaultTestExcludedModulesEventSubscriberTest+MenuLinksTest: create menus with underscores, not hyphens 🤷♀️ Easy fix!MigrateShortcutSetTest+MigrateShortcutSetUsersTest+MigrateShortcutTest+actionandtourhave updated machine name regexes, so their tests are now of course failing. Easy fix!… which should make this green! 🤞
Comment #60
wim leersI see I uploaded the wrong interdiff for #59 🙈
All interdiffs starting at #53 and ending at #59 were about not creating a follow-up like the 3 we already have for widely violated validation constraints. While not complex, it does require pervasive changes: the patch grew from 32.12 KiB to 61.44 KiB. Almost double!
Proposal for keeping this issue actionable
I propose to not do what I was hoping for in #54: to reduce the scope of this issue and just ignore validation violations for machine names for now. That does require keeping some of the changes between #53 and #59, to allow us to actually detect specifically
type: machine_nameviolations instead of genericRegExconstraint violations.Follow-up: #3372972: Fix all type: machine_name constraint violations in tests.
Working to move most of #53 through #59 out of this patch and into the follow-up…
Comment #61
wim leersThis goes back to #52, but adds #53 + #57. That means we're not changing anything WRT machine name validations here except for the message, so we can explicitly exempt it for now.
That is not a BC break, because #2920678: Add config validation for the allowed characters of machine names landed in
10.2.x, not10.1.x.Comment #62
wim leersNow actually add
to
$ignored_validation_constraint_messagesinSchemaCheckTrait, so that this passes tests once again 😊Comment #63
borisson_As mentioned in #44, we should make this early in the 10.2 release cycle, we still have the time to do that. Moving this to rtbc. I agree with keeping this smaller so that the followups can fix the remaining errors.
This was already rtbc in #41 and in the meantime @Wim Leers made everything green but has removed most of those fixes again to make this patch smaller.
Comment #64
wim leersThanks for the swift review, @borisson_!
Updated the issue summary for core committers to help them assess the ecosystem impact. (If preferred, we could change it so that only core tests are affected, and for contrib we'd make config schema checks that fail only due to validation errors trigger deprecation errors instead.)
Comment #65
borisson_I talked to @longwave about this issue earlier today at drupal dev days, we figured that #2972573: randomMachineName() should conform to processMachineName() pattern (now back to rtbc), was a blocker for this, but because of #62 (where we are ignoring the machine name errors in the tests, but making the validation already happen), this is actually not a blocker.
I think this can be committed as-is and in a follow-up we can remove the ignoring of the machine name errors and make sure they use the new Random machine name generator and that they are all correct in the tests.
Comment #67
wim leers#3373653: Add a `langcode` data type to config schema landed and caused many new test failures! Let's find out if we can fix them here easily or whether it warrants a new follow-up issue…
Comment #68
wim leersTurns out that #3373653: Add a `langcode` data type to config schema was awesome but missed one edge case 😅 Not its fault though: the problem is that test coverage is all implicit, and this issue is the one that makes it somewhat more explicit!
Comment #69
wim leersAight, #68 seems to be passing all of the kernel tests that failed in #62 ever since
type: langcodelanded. 👍If #65 is true, we should be able to remove
because #2972573: randomMachineName() should conform to processMachineName() pattern landed.
Let's find out.
Comment #70
wim leers#69 surfaces an oversight in #2920678: Add config validation for the allowed characters of machine names: the IDs of
actionconfig entities can contain periods — seeuser_user_role_insert()for at 2 examples:There is barely any test coverage for the Action functionality, which is how this slipped through the cracks. Which coincidentally is one of the reasons that Drupal core is working to remove the Action module: #3343369: [meta] Tasks to deprecate Actions UI module .
Anyway, it's easy enough to fix: just tweak the regex!
Comment #72
wim leersWhat I wrote in #70 about
actionconfig entities is also true fortourconfig entities…I'd swear I've made exactly these tweaks before in another issue! 😳 Did I dream it? 🙈Nope, I didn't dream it — that's what I said in #60 😅 That's what #3372972: Fix all type: machine_name constraint violations in tests is for, and we still need it — because there's much more to fix than only #2972573: randomMachineName() should conform to processMachineName() pattern!
Continuing #68, abandoning #69 + #70 — those belong in that follow-up.
Comment #73
borisson_Back to rtbc. This issue has surfaced a couple of issues with our configuration schema's and I think this would make the other issues dealing with configuration schema's even more correct on their first attempts.
Comment #74
lauriiiAre we removing this because
\Drupal\Core\Config\Schema\SchemaCheckTrait::checkConfigSchemadoes more now, and would therefore find violations?Does these need to be update hooks or could these be implemented as post update?
Comment #75
wim leers#74:
::checkConfigSchema()does more now: it also applies validation. And in this particular case, we were asserting that the config schema storage types complied, even if it was invalid. Note this was anassert()call, so it already was entirely optional, and only intended to simplify things for developers. Now that CKEditor 5 is fully mature, there's no need for this anymore anyway.olivero_post_update_add_olivero_primary_color()andsystem_post_update_remove_asset_entries()are setting a new example, so … following that instead! (In hindsight: makes sense: we're not repairing a broken Drupal, we're using the existing APIs, so we must use the post-update system 👍)Self-re-RTBC'ing because this is literally just renaming+moving functions, there's no logic changes at all. Even the update path tests don't need to change!
Comment #76
wim leersFYI:
These and other
demo_umamichanges here can be removed from this issue if #3377055: Validate config schema compliance of Demo Umami and Minimal profiles, just like we do for Standard lands first.Comment #77
longwaveWhitespace change to an otherwise unchanged file is out of scope.
This is changed here and in an update hook, but the UI doesn't handle nullable values:
iframe_domainis''instead of~ornull.I suspect it might be the same for the other nullable URI config values?
Should we allow empty string to be a valid URI, and instead not allow URI to be null?
Comment #78
wim leers#75 failed tests. Turns out
@coverssyntax is tricky.I missed this because PHPStan often refuses to work locally with certain contrib modules installed…
Comment #79
wim leers#77:
''toNULL, to ensure config remains valid.Wait for #3364506: Add optional validation constraint support to ConfigFormBase to land, then adoptSilly me — that won't work! 😅 It won't work because it still needs to be possible to not enter an iframe domain.ValidatableConfigFormBasehere, and then the empty string would trigger a validation error.So went with option 1. Hope you like it. 🤓
update.settings:fetch.urlis not affected becauseUpdateSettingsFormdoes not modify it. Similarly,system.theme.global:logo.urlis not affected becauseThemeSettingsFormonly supports modifyingsystem.theme.global:logo.path— in fact, it turns out thatlogo.urlis computed at runtime only, bytheme_get_setting()😳 Looks like this is such an obscure part of the theme system that there is not even a single issue about it 😳 Either way: that's unaffected, and any improvements in the theme system are out-of-scope here (although I'm happy to file an issue against the theme system if you like.)Also: GREAT catch! If there were a functional test of the media settings UI, the very test coverage introduced here would've detected it… 😬 So now I'm wondering if you want me to write test coverage for that? 🤔 It seems not worth it on the one hand, but on the other hand it may be valuable as a stepping stone in bringing config validation to core. Thoughts?
Comment #80
longwaveI think test coverage will be nice here and hopefully not take long. It proves that we need functional test coverage to catch some of these cases - we're likely to have to introduce more of it as we go along, so let's set a good precedent by starting here.
Agree that the other two aren't affected, and yes let's open a followup issue to remove
system.theme.global:logo.urlfrom config given it shouldn't be stored anyway.I think we could get away with
but it's not as technically accurate as the exact check...
Comment #81
wim leersIssue summary updates for #74–#79.
Comment #82
wim leers@longwave in Slack:
On it 👍
Comment #83
wim leersExplicit test coverage for `MediaSettingsForm` setting `media.settings:iframe_domain` to `null`.
Comment #84
borisson_This was quick, Test coverage now proves that this should always be `null` instead of an empty string, that is how we configured the schema as well so that looks great.
Comment #86
lauriiiWe could probably simplify this by using filled database but don't think this needs to block this.
Going ahead and committing this to enable all of the config validation efforts to move forward. I discussed this with @catch earlier and he was onboard with this in principle.
Committed f13ad69 and pushed to 11.x. Thanks!
Comment #87
wim leers🥳🚀
Now we're really off to the races!
Every next addition of validation constraints will instantly get a solid overview of invalid config in tests! Starting with #3376794: `type: mapping` should use `ValidKeys: <infer>` constraint by default and #3341682: New config schema data type: `required_label`.
Plus, this unblocks 4 follow-ups:
All 4 already have MRs, and 3 of the 4 are mostly done! Currently working on #3372972: Fix all type: machine_name constraint violations in tests 🤓
Comment #88
wim leersAll 4 follow-ups have landed already, the last one about a week ago! 🚀
Next up: #3364109: Configuration schema & required values: add test coverage for `nullable: true` validation support, which will trigger an even bigger set of follow-up issues.
Comment #89
jibranDynamic Entity Reference views test started failing https://app.circleci.com/pipelines/github/jibran/dynamic_entity_referenc... since this commit.
Can I have a quick pointer how to fix the test? I had a look at the change record but it was not helpful.
Comment #90
wim leers@jibran: Wow you're already testing against
11.x?! I think you're probably literally the only contrib module who does that; you'd have to patch your*.info.ymlfile for that to be possible too 😅An actual answer:
$constraint_manager = $this->getTypedDataManager()->getValidationConstraintManager();results inconstraint_managerin your test. But that line is not new nor changed here, it's existed since 2015 😬Turns out that it is a bug in your test, which you copied straight from core's buggy test at
\Drupal\Tests\views\Kernel\TestViewsTest::testDefaultConfig(), which this issue indeed fixed.The change you need:
Because you're WAY ahead of the pack, I've gone ahead and prioritized fixing that: created #3379899: Follow-up for #3361534: config validation errors in contrib modules should cause deprecation notices, not test failures 👍
Thank you! 😊🙏
Comment #91
jibran@Wim Leers thank you for the kind words. I run test against HEAD every morning on CircleCI. The tests starts failing since the commit was made and I was just lazy in fixing it. :D
Thank you for jumping on to it and helping me with the fix. I have pushed the fix to both DER 3.x and 4.x.
Comment #92
jibranCommitted and push 39cc0a2 and it is all green
https://app.circleci.com/pipelines/github/jibran/dynamic_entity_referenc....
Comment #93
wim leersAwesome! 😊
I checked your commit history and I bet that this commit on July 5 further increases your likelihood of winning the "first contrib module to test against Drupal 11"-award 🥇😄
Comment #94
wim leersComment #96
effulgentsia commentedHi. I'm coming here while reviewing #3364109: Configuration schema & required values: add test coverage for `nullable: true` validation support as part of background research for it. I see that this issue added:
for some? all? URI types.
However,
SchemaCheckTraitalready allows all primitive types to be null. So why was it necessary to add the additionalnullable: truefor URIs?Comment #97
wim leers@effulgentsia: see point 2 in the proposed resolution.