Update config validation logic for entities#3306
Conversation
There was a problem hiding this comment.
Pull request overview
Adds a CLI validation-time warning to help users detect “valid” configs that define no entities (and have no autoentities / multi-config datasource files), aligning dab validate behavior with Issue #3267.
Changes:
- Adds a
WarnIfNoEntitiesDefined(RuntimeConfig)helper and invokes it duringdab validate. - Refactors
IsConfigValidto log the new structural warning regardless of overall validation outcome. - Adds a CLI unit test that verifies the warning is logged for a minimal config with zero entities.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| src/Cli/ConfigGenerator.cs | Introduces and invokes the new “zero entities” warning helper during dab validate. |
| src/Cli.Tests/ValidateConfigTests.cs | Adds a unit test verifying the warning is emitted for an empty-entities config. |
|
/azp run |
after offline discussion |
…zero-entities-validate
4bb0609 to
5c93d5e
Compare
| Runtime.Rest is null || | ||
| Runtime.Rest.Enabled) && | ||
| DataSource.DatabaseType != DatabaseType.CosmosDB_NoSQL; | ||
| DataSource?.DatabaseType != DatabaseType.CosmosDB_NoSQL; |
There was a problem hiding this comment.
If DataSource is not present in case of root config, this will evaluate to false even though the child configs with a DataSource are of type SQL.
The condition should be either its null or if not null, Db type !=NoSQL
| if (!TryCreateSourceObjectForNewEntity( | ||
| options, | ||
| initialRuntimeConfig.DataSource.DatabaseType == DatabaseType.CosmosDB_NoSQL, | ||
| initialRuntimeConfig.DataSource!.DatabaseType == DatabaseType.CosmosDB_NoSQL, |
There was a problem hiding this comment.
how are we sure DataSource is not null here?
What happens when a new entity is being added to a config with a null data source? Is that allowed? If not, where is the check that will prevent this?
| [NotNullWhen(true)] ref RuntimeConfig runtimeConfig) | ||
| { | ||
| DatabaseType dbType = runtimeConfig.DataSource.DatabaseType; | ||
| DatabaseType dbType = runtimeConfig.DataSource!.DatabaseType; |
There was a problem hiding this comment.
How can we be sure DataSource is null when trying to update the datasource? Does the caller perform any checks?
Same question for all null forgiveness operator usage in this file.
| ""entities"": {} | ||
| }"; | ||
|
|
||
| // The root config should parse without error (no data-source required for root). |
There was a problem hiding this comment.
Shouldnt the test also check that IsConfigValid returns true?
| [TestMethod] | ||
| public void TestNonRootConfigWithDataSourceAndNoEntitiesParses() | ||
| { | ||
| Assert.IsTrue(RuntimeConfigLoader.TryParseConfig(INITIAL_CONFIG, out RuntimeConfig? config)); |
There was a problem hiding this comment.
What makes this a Non root config? Does INITIAL_CONFIG string specify that?
| [TestMethod] | ||
| public void TestNonRootWithDataSourceAndNoEntitiesProducesError() | ||
| { | ||
| RuntimeConfig config = BuildTestConfig(hasDataSource: true, entities: new()); |
There was a problem hiding this comment.
What makes it non-root?
Aniruddh25
left a comment
There was a problem hiding this comment.
IsRestEnabled check needs to be fixed.
Why make this change?
Closes #3267
What is this change?
Alters the validation logic in the following way.
Is top-level config with data-source-files?
├── YES
│ ├── Has datasource? → ValidateEntityPresence (same rules as non-root)
│ ├── No datasource but has entities/autoentities? → ERROR
│ └── No datasource, no entities → VALID (children provide everything)
│ └── For each child → ValidateNonRootConfig(child, filename)
│
└── NO (standalone or child config)
├── No datasource? → ERROR: "data source is required"
└── Has datasource → ValidateEntityPresence
ValidateEntityPresence
Count resolved autoentities from AutoentityResolutionCounts
total = manual entities + resolved autoentities
total == 0? → ERROR: "No entities found"
total > 0 but autoentities discovered nothing? → WARN: "Autoentities configured but none discovered"
No double messaging. If total is 0, only the error is recorded, not the warning.
How was this tested?
Truth table — top-level config
Variables (
1= present / non-empty,0= absent / empty):data-source-filespresentdata-sourcepresententitiescount > 0autoentitiescount > 0 (presence, not resolved count)Path is determined by
IsRootConfig = (DSF == 1) && !IsChildConfig.TestNonRootWithNoDataSourceProducesErrorTestNonRootWithDataSourceAndNoEntitiesProducesErrorTestNonRootWithDataSourceAndAutoentitiesResolvingZeroProducesErrorTestNonRootWithDataSourceAndAutoentitiesResolvingEntitiesIsValidTestNonRootWithDataSourceAndEntitiesIsValidTestNonRootWithEntitiesAndAutoentitiesResolvingZeroLogsWarningTestRootWithNoDataSourceAndNoEntitiesIsValid,TestRootConfigWithNoDataSourceAndNoEntitiesParsesTestRootWithNoDataSourceButAutoentitiesProducesErrorTestRootWithNoDataSourceButEntitiesProducesErrorTestRootWithDataSourceAndNoEntitiesProducesErrorTestRootWithDataSourceAndAutoentitiesResolvingZeroProducesErrorTestRootWithDataSourceAndAutoentitiesResolvingEntitiesIsValidTestRootWithDataSourceAndEntitiesIsValidTestRootWithEntitiesAndAutoentitiesResolvingZeroLogsWarningTruth table — child config (validated when iterating
root.ChildConfigs)Children are always treated as non-root regardless of their own
data-source-files.TestChildWithNoDataSourceProducesNamedErrorTestChildWithDataSourceAndNoEntitiesProducesNamedErrorTestChildWithDataSourceAndAutoentitiesResolvingZeroProducesNamedErrorTestRootWithDataSourceAndEntitiesIsValidsetupTestChildWithEntitiesAndAutoentitiesResolvingZeroLogsNamedWarningOther scenarios
IsConfigValid == falsedue to connection error onlyTestValidateNonRootZeroEntitiesWithInvalidConnectionStringIsConfigValidreturns false without throwingTestValidateConfigWithNoEntitiesProducesCleanError(modified)IsRootConfig == trueTestRootConfigWithNoDataSourceAndNoEntitiesParsesIsRootConfig == falseTestNonRootConfigWithDataSourceAndNoEntitiesParsesValidateAutoentitiesConfiguration(modified toisValidateOnly: true)New tests:
TestRootConfigWithNoDataSourceAndNoEntitiesParsesRoot config (has data-source-files) without datasource parses OKTestNonRootConfigWithDataSourceAndNoEntitiesParsesNon-root config with datasource + no entities parses OK (validation catches it later)TestNonRootWithDataSourceAndNoEntitiesProducesErrorCalls ValidateDataSourceAndEntityPresence directly, error recordedTestNonRootWithNoDataSourceProducesErrorNo datasource, error with "data source is required"TestNonRootWithDataSourceAndEntitiesIsValidDatasource + entities, no errorsTestRootWithNoDataSourceAndNoEntitiesIsValidRoot with child, no own datasource, validTestRootWithNoDataSourceButEntitiesProducesErrorRoot with entities but no datasource, errorTestRootWithDataSourceAndEntitiesIsValidRoot with own datasource + entities, validTestChildWithDataSourceAndNoEntitiesProducesNamedErrorChild with no entities, error names the child fileTestChildWithNoDataSourceProducesNamedErrorChild with no datasource, error names the child fileTestNonRootWithDataSourceAndAutoentitiesResolvingZeroProducesErrorNon-root with only autoentities that resolve to 0TestNonRootWithDataSourceAndAutoentitiesResolvingEntitiesIsValidNon-root with only autoentities resolving > 0 entitiesTestNonRootWithEntitiesAndAutoentitiesResolvingZeroLogsWarningNon-root with manual entities + autoentities resolving 0TestRootWithNoDataSourceButAutoentitiesProducesErrorRoot with no datasource but autoentities definedTestRootWithDataSourceAndNoEntitiesProducesErrorRoot with own datasource and zero entities/autoentitiesTestRootWithDataSourceAndAutoentitiesResolvingZeroProducesErrorRoot with own datasource and autoentities resolving 0TestRootWithDataSourceAndAutoentitiesResolvingEntitiesIsValidRoot with own datasource and autoentities resolving > 0TestRootWithEntitiesAndAutoentitiesResolvingZeroLogsWarningRoot with own datasource, manual entities, and autoentities resolving 0TestChildWithDataSourceAndAutoentitiesResolvingZeroProducesNamedErrorChild with autoentities-only resolving 0TestChildWithEntitiesAndAutoentitiesResolvingZeroLogsNamedWarningChild with manual entities + autoentities resolving 0Modified tests:
TestValidateConfigWithNoEntitiesProducesCleanErrorReplaced main's version (expected parse failure) with ours: parse succeeds, IsConfigValid returns falseValidateAutoentitiesConfigurationChanged to isValidateOnly: true, asserts no crashes instead of zero errors