Skip to content

Commit fefffea

Browse files
authored
Fix: propagate autoentity resolution counts to child configs during validation
When using `data-source-files`, the metadata provider stores autoentity resolution counts only on the root (merged) config. ValidateRootConfig now copies those counts to each child config before per-child validation, so child configs with only autoentities correctly pass the entity-presence check instead of failing with "No entities found". Adds two regression tests: - TestChildWithDataSourceAndAutoentitiesResolvingEntitiesIsValid - TestRootAndChildBothWithAutoentitiesResolvingEntitiesIsValid
1 parent 448161e commit fefffea

2 files changed

Lines changed: 78 additions & 0 deletions

File tree

src/Cli.Tests/ValidateConfigTests.cs

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -883,6 +883,72 @@ public void TestChildWithEntitiesAndAutoentitiesResolvingZeroLogsNamedWarning()
883883
VerifyAutoentityZeroDiscoveredWarning(loggerMock, expectedFileNameInMessage: "child-db.json");
884884
}
885885

886+
/// <summary>
887+
/// Child config with only autoentities that resolve to >0 entities is valid.
888+
/// Simulates the production code path where the metadata provider stores resolution
889+
/// counts on the root (merged) config rather than on the child config directly.
890+
/// This is the regression test for the bug where child-config autoentities caused
891+
/// "No entities found" even when they were expanded successfully.
892+
/// Covers child truth-table row C5 (DS=1, E=0, AE=1, resolved>0, counts on root).
893+
/// </summary>
894+
[TestMethod]
895+
public void TestChildWithDataSourceAndAutoentitiesResolvingEntitiesIsValid()
896+
{
897+
// Child has no explicit entities; only autoentities.
898+
RuntimeConfig childConfig = BuildTestConfig(
899+
hasDataSource: true,
900+
entities: new(),
901+
autoentities: new() { { "ae1", BuildSimpleAutoentity() } });
902+
childConfig.IsChildConfig = true;
903+
904+
RuntimeConfig rootConfig = BuildTestConfig(
905+
hasDataSource: false, entities: new(),
906+
dataSourceFiles: new DataSourceFiles(new[] { "child-db.json" }));
907+
rootConfig.ChildConfigs.Add(("child-db.json", childConfig));
908+
909+
// Simulate production: metadata provider stores counts in the root config,
910+
// NOT directly on the child config.
911+
rootConfig.AutoentityResolutionCounts["ae1"] = 3;
912+
913+
RuntimeConfigValidator validator = BuildValidator(rootConfig);
914+
validator.ValidateDataSourceAndEntityPresence(rootConfig);
915+
916+
Assert.AreEqual(0, validator.ConfigValidationExceptions.Count,
917+
"Child config with autoentities that resolved entities should pass validation.");
918+
}
919+
920+
/// <summary>
921+
/// Both root and child configs have autoentities that resolve to >0 entities.
922+
/// Resolution counts for both are stored only on the root config (as the metadata
923+
/// provider does at runtime). Validation must pass for both configs.
924+
/// </summary>
925+
[TestMethod]
926+
public void TestRootAndChildBothWithAutoentitiesResolvingEntitiesIsValid()
927+
{
928+
RuntimeConfig childConfig = BuildTestConfig(
929+
hasDataSource: true,
930+
entities: new(),
931+
autoentities: new() { { "child-ae", BuildSimpleAutoentity() } });
932+
childConfig.IsChildConfig = true;
933+
934+
RuntimeConfig rootConfig = BuildTestConfig(
935+
hasDataSource: true,
936+
entities: new(),
937+
dataSourceFiles: new DataSourceFiles(new[] { "child-db.json" }),
938+
autoentities: new() { { "root-ae", BuildSimpleAutoentity() } });
939+
rootConfig.ChildConfigs.Add(("child-db.json", childConfig));
940+
941+
// Simulate production: metadata provider stores ALL counts in the root config.
942+
rootConfig.AutoentityResolutionCounts["root-ae"] = 2;
943+
rootConfig.AutoentityResolutionCounts["child-ae"] = 4;
944+
945+
RuntimeConfigValidator validator = BuildValidator(rootConfig);
946+
validator.ValidateDataSourceAndEntityPresence(rootConfig);
947+
948+
Assert.AreEqual(0, validator.ConfigValidationExceptions.Count,
949+
"Root and child configs both with autoentities that resolved entities should pass validation.");
950+
}
951+
886952
/// <summary>
887953
/// Helper: verifies that the autoentity-discovered-zero warning was logged at least once,
888954
/// optionally also checking that the formatted message contains a child config file name.

src/Core/Configurations/RuntimeConfigValidator.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -739,6 +739,18 @@ private void ValidateRootConfig(RuntimeConfig runtimeConfig)
739739
// Validate each child config independently.
740740
foreach ((string fileName, RuntimeConfig childConfig) in runtimeConfig.ChildConfigs)
741741
{
742+
// The metadata provider stores autoentity resolution counts on the root (merged)
743+
// config. Copy those counts to the child config so per-child validation can find
744+
// them. Only copy if the child hasn't already been populated (e.g. in unit tests).
745+
foreach (KeyValuePair<string, Autoentity> ae in childConfig.Autoentities)
746+
{
747+
if (!childConfig.AutoentityResolutionCounts.ContainsKey(ae.Key)
748+
&& runtimeConfig.AutoentityResolutionCounts.TryGetValue(ae.Key, out int count))
749+
{
750+
childConfig.AutoentityResolutionCounts[ae.Key] = count;
751+
}
752+
}
753+
742754
ValidateNonRootConfig(childConfig, configName: fileName);
743755
}
744756
}

0 commit comments

Comments
 (0)