fix(sql): a skipped tag reports the deploy gate's reason, pinned for the deferred Query model (R06:S-4)
A model:Query tag reached the runtime skip ledger as a generic 'did not map'. The ledger reason (and the skip warning) now comes from SqlTagDefinitionFactory.Inspect - the deploy gate's own explanation over the same parser - so /hosts names the deferral. A test pins that the deploy gate names Query through the parser. Making it a hard deploy error in Warn mode is a ControlPlane change (follow-up); MySql/Odbc and allowWrites remain feature issues. Refs #744 Claude-Session: https://claude.ai/code/session_01Ub9hGmYLQvn9XETzw7CMsT
This commit is contained in:
@@ -929,10 +929,15 @@ public sealed class SqlDriver
|
||||
table[entry.RawPath] = definition;
|
||||
else
|
||||
{
|
||||
blobSkips.Add(new SkippedTag(entry.RawPath, "TagConfig did not map to a definition"));
|
||||
// The reason is the DEPLOY GATE's own explanation (R06:S-4) — SqlTagDefinitionFactory.Inspect
|
||||
// asks this same parser and then says why — so /hosts names e.g. the deferred Query model
|
||||
// instead of a generic "did not map" for a tag the gate already warned about.
|
||||
var reason = SqlTagDefinitionFactory.Inspect(entry.TagConfig).FirstOrDefault()
|
||||
?? "TagConfig did not map to a definition";
|
||||
blobSkips.Add(new SkippedTag(entry.RawPath, reason));
|
||||
_logger.LogWarning(
|
||||
"Sql tag config did not map to a definition; skipping. Driver={DriverInstanceId} RawPath={RawPath}",
|
||||
_driverInstanceId, entry.RawPath);
|
||||
"Sql tag config did not map to a definition; skipping. Driver={DriverInstanceId} RawPath={RawPath} Reason={Reason}",
|
||||
_driverInstanceId, entry.RawPath, reason);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
||||
@@ -464,6 +464,26 @@ public sealed class SqlDriverTests
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <b>R06:S-4.</b> A skipped tag's ledger reason (what /hosts shows) is the deploy gate's own explanation
|
||||
/// — for a <c>Query</c> tag, that the model is deferred — instead of a generic "did not map". Control: a
|
||||
/// well-formed tag is not skipped at all.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public async Task ADeferredQueryTag_isSkipped_withTheGatesReason()
|
||||
{
|
||||
using var fixture = new SqlitePollFixture();
|
||||
await using var driver = NewDriver(fixture,
|
||||
KvEntry("Speed", SqlitePollFixture.PresentKey),
|
||||
new RawTagEntry("Q", """{"driver":"Sql","model":"Query","table":"T","query":"SELECT 1"}""", WriteIdempotent: false));
|
||||
await driver.InitializeAsync(ConfigJson, CancellationToken.None);
|
||||
|
||||
var report = ((ISkippedTagReporter)driver).GetSkippedTags().ShouldNotBeNull();
|
||||
var skipped = report.Sample.ShouldHaveSingleItem();
|
||||
skipped.RawPath.ShouldBe("Q");
|
||||
skipped.Reason.ShouldContain("Query");
|
||||
}
|
||||
|
||||
// ---- Driver.Sql-010: the health field is read-modify-written from several poll loops ----
|
||||
|
||||
[Fact]
|
||||
|
||||
@@ -232,6 +232,21 @@ public class SqlEquipmentTagParserTests
|
||||
SqlEquipmentTagParser.TryParse(json, "raw", out _).ShouldBeFalse();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <b>R06:S-4.</b> The deploy gate (<c>EquipmentTagConfigInspector</c>) reaches this through the parser:
|
||||
/// a <c>Query</c> tag draws a warning naming the deferral (a rejection under TagConfigValidation=Error).
|
||||
/// Control: a served key-value blob draws nothing.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void Inspect_theDeferredQueryModel_isNamedAtTheDeployGate()
|
||||
{
|
||||
SqlTagDefinitionFactory.Inspect("""{"driver":"Sql","model":"Query","table":"T","query":"SELECT 1"}""")
|
||||
.ShouldHaveSingleItem().ShouldContain("Query");
|
||||
SqlTagDefinitionFactory.Inspect(
|
||||
"""{"driver":"Sql","model":"KeyValue","table":"T","keyColumn":"k","keyValue":"v","valueColumn":"c"}""")
|
||||
.ShouldBeEmpty();
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("""{"driver":"Sql","model":"KeyValue","keyColumn":"k","keyValue":"v","valueColumn":"c"}""")]
|
||||
[InlineData("""{"driver":"Sql","model":"KeyValue","table":"","keyColumn":"k","keyValue":"v","valueColumn":"c"}""")]
|
||||
|
||||
Reference in New Issue
Block a user