worker(alarms): fix net48 build (init->set, usings), token-boundary name parse, acked latch, dup-address guard, tests

This commit is contained in:
Joseph Doherty
2026-06-13 09:05:58 -04:00
parent 348ab16456
commit b10e103bcf
4 changed files with 138 additions and 25 deletions
@@ -33,6 +33,58 @@ public sealed class SubtagAlarmStateMachineTests
Assert.Equal(MxAlarmStateKind.UnackAlm, e.Record.State);
Assert.Equal(MxAlarmStateKind.Unspecified, e.PreviousState);
Assert.Equal("Tank01.Level.HiHi", e.Record.TagName);
Assert.Equal("Galaxy", e.Record.ProviderName);
Assert.Equal("Area", e.Record.Group);
}
[Fact]
public void ActiveFalseToTrue_NoProviderBang_UsesWholeReferenceAsTagName()
{
var target = new AlarmSubtagTarget
{
AlarmFullReference = "Tank01.Level.HiHi",
SourceObjectReference = string.Empty,
ActiveSubtag = "Tank01.Level.HiHi.active",
};
var sm = new SubtagAlarmStateMachine(new[] { target });
var ts = new DateTime(2026, 6, 13, 9, 0, 0, DateTimeKind.Utc);
var events = sm.Apply("Tank01.Level.HiHi.active", true, ts);
var e = Assert.Single(events);
Assert.Equal("Tank01.Level.HiHi", e.Record.TagName);
Assert.Equal(string.Empty, e.Record.ProviderName);
Assert.Equal(string.Empty, e.Record.Group);
}
[Fact]
public void OutOfOrderAckThenClear_StillEmitsAckRtn()
{
var sm = new SubtagAlarmStateMachine(new[] { Target() });
var ts = new DateTime(2026, 6, 13, 9, 0, 0, DateTimeKind.Utc);
sm.Apply("Tank01.Level.HiHi.active", true, ts);
sm.Apply("Tank01.Level.HiHi.acked", true, ts.AddSeconds(2));
// Out-of-order un-ack arrives before the active=false clear.
sm.Apply("Tank01.Level.HiHi.acked", false, ts.AddSeconds(3));
var events = sm.Apply("Tank01.Level.HiHi.active", false, ts.AddSeconds(10));
var e = Assert.Single(events);
Assert.Equal(MxAlarmStateKind.AckRtn, e.Record.State);
}
[Fact]
public void DuplicateActiveSubtag_Throws()
{
var first = new AlarmSubtagTarget
{
AlarmFullReference = "Galaxy!Area.Tank01.Level.HiHi",
SourceObjectReference = "Tank01",
ActiveSubtag = "Shared.active",
};
var second = new AlarmSubtagTarget
{
AlarmFullReference = "Galaxy!Area.Tank02.Level.HiHi",
SourceObjectReference = "Tank02",
ActiveSubtag = "Shared.active",
};
Assert.Throws<ArgumentException>(() => new SubtagAlarmStateMachine(new[] { first, second }));
}
[Fact]