fix(scripted-alarms): harden artifact boolean decode + direct helper tests (T6 review)
Default HistorizeToAveva/Retain/Enabled to the entity defaults (true) when a
field is absent/null/non-boolean so a partial blob decodes identically to the
composer's view of a default-constructed ScriptedAlarm (byte-parity), and only
call GetBoolean for a genuine true/false token. Add direct ExtractAlarmDependencyRefs
unit tests (overlap dedup + reserved {{equip}} exclusion).
This commit is contained in:
@@ -653,12 +653,16 @@ public static class DeploymentArtifact
|
|||||||
var severity = el.TryGetProperty("Severity", out var svEl) && svEl.TryGetInt32(out var sv) ? sv : 0;
|
var severity = el.TryGetProperty("Severity", out var svEl) && svEl.TryGetInt32(out var sv) ? sv : 0;
|
||||||
var messageTemplate = el.TryGetProperty("MessageTemplate", out var mtEl) ? mtEl.GetString() : null;
|
var messageTemplate = el.TryGetProperty("MessageTemplate", out var mtEl) ? mtEl.GetString() : null;
|
||||||
var predicateScriptId = el.TryGetProperty("PredicateScriptId", out var psEl) ? psEl.GetString() : null;
|
var predicateScriptId = el.TryGetProperty("PredicateScriptId", out var psEl) ? psEl.GetString() : null;
|
||||||
var historize = el.TryGetProperty("HistorizeToAveva", out var hEl) && hEl.ValueKind != JsonValueKind.Null
|
// Booleans default to the entity defaults (true) when absent / null / non-boolean, so a
|
||||||
? hEl.GetBoolean() : false;
|
// partial blob decodes the same as the composer's view of a default-constructed
|
||||||
var retain = el.TryGetProperty("Retain", out var rEl) && rEl.ValueKind != JsonValueKind.Null
|
// ScriptedAlarm — preserving byte-parity. GetBoolean only runs for a genuine true/false
|
||||||
? rEl.GetBoolean() : false;
|
// token (a non-bool token would otherwise throw InvalidOperationException, uncaught here).
|
||||||
var enabled = el.TryGetProperty("Enabled", out var enEl) && enEl.ValueKind != JsonValueKind.Null
|
bool ReadBool(string prop, bool dflt) =>
|
||||||
? enEl.GetBoolean() : false;
|
el.TryGetProperty(prop, out var b) && b.ValueKind is JsonValueKind.True or JsonValueKind.False
|
||||||
|
? b.GetBoolean() : dflt;
|
||||||
|
var historize = ReadBool("HistorizeToAveva", true);
|
||||||
|
var retain = ReadBool("Retain", true);
|
||||||
|
var enabled = ReadBool("Enabled", true);
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(scriptedAlarmId)) continue;
|
if (string.IsNullOrWhiteSpace(scriptedAlarmId)) continue;
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,33 @@ namespace ZB.MOM.WW.OtOpcUa.Commons.Tests;
|
|||||||
|
|
||||||
public class EquipmentScriptPathsTests
|
public class EquipmentScriptPathsTests
|
||||||
{
|
{
|
||||||
|
// ---- ExtractAlarmDependencyRefs (scripted-alarm dep graph; byte-parity seam) ----
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void ExtractAlarmDependencyRefs_predicate_reads_first_then_template_tokens_deduped()
|
||||||
|
{
|
||||||
|
// A template token identical to a predicate read appears once (predicate-first); a distinct
|
||||||
|
// template token is appended after. This dedup/order is the parity contract both the composer
|
||||||
|
// and the artifact decode rely on.
|
||||||
|
EquipmentScriptPaths
|
||||||
|
.ExtractAlarmDependencyRefs(
|
||||||
|
predicateSource: "return ctx.GetTag(\"Mach.Temp\").Value > 90;",
|
||||||
|
messageTemplate: "Temp {Mach.Temp} over {Mach.Limit}")
|
||||||
|
.ShouldBe(["Mach.Temp", "Mach.Limit"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void ExtractAlarmDependencyRefs_excludes_reserved_equip_double_brace_token()
|
||||||
|
{
|
||||||
|
// The reserved {{equip}} double-brace form must NOT be picked up as a single-brace {TagPath}
|
||||||
|
// token; only the genuine {Line.Temp} token is extracted.
|
||||||
|
EquipmentScriptPaths
|
||||||
|
.ExtractAlarmDependencyRefs(
|
||||||
|
predicateSource: null,
|
||||||
|
messageTemplate: "{{equip}} too hot: {Line.Temp}")
|
||||||
|
.ShouldBe(["Line.Temp"]);
|
||||||
|
}
|
||||||
|
|
||||||
// ---- DeriveEquipmentBase ----
|
// ---- DeriveEquipmentBase ----
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|||||||
Reference in New Issue
Block a user