contracts: round-trip degraded provenance/watch-list/mode-changed; proto doc (Contracts-018,019)
This commit is contained in:
@@ -1427,4 +1427,120 @@ public sealed class ProtobufContractRoundTripTests
|
||||
Assert.Single(parsed.ReadBulk.Results);
|
||||
Assert.True(parsed.ReadBulk.Results[0].WasCached);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verifies that an <see cref="ActiveAlarmSnapshot"/> carrying the
|
||||
/// alarm-provider provenance fields <c>degraded</c> (14) and
|
||||
/// <c>source_provider</c> (15) round-trips with their values preserved,
|
||||
/// pinning the wire shape of the byte-identical provenance fields that
|
||||
/// also appear on <see cref="OnAlarmTransitionEvent"/>.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void ActiveAlarmSnapshot_RoundTripsDegradedProvenance()
|
||||
{
|
||||
var raise = Timestamp.FromDateTime(new DateTime(2026, 6, 13, 12, 0, 0, DateTimeKind.Utc));
|
||||
var original = new ActiveAlarmSnapshot
|
||||
{
|
||||
AlarmFullReference = "Galaxy!Area.Tank01.Level.HiHi",
|
||||
SourceObjectReference = "Tank01",
|
||||
AlarmTypeName = "AnalogLimitAlarm.HiHi",
|
||||
Severity = 750,
|
||||
OriginalRaiseTimestamp = raise,
|
||||
CurrentState = AlarmConditionState.Active,
|
||||
Degraded = true,
|
||||
SourceProvider = AlarmProviderMode.Subtag,
|
||||
};
|
||||
|
||||
var parsed = ActiveAlarmSnapshot.Parser.ParseFrom(original.ToByteArray());
|
||||
|
||||
Assert.Equal(original, parsed);
|
||||
Assert.True(parsed.Degraded);
|
||||
Assert.Equal(AlarmProviderMode.Subtag, parsed.SourceProvider);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verifies that a <see cref="SubscribeAlarmsCommand"/> populating the
|
||||
/// alarm-provider fallback extensions — <c>forced_mode</c> (2), a
|
||||
/// <c>watch_list</c> entry with all six <see cref="AlarmSubtagTarget"/>
|
||||
/// string fields (3), and a <c>failover</c>
|
||||
/// <see cref="AlarmFailoverConfig"/> (4) — round-trips end to end,
|
||||
/// pinning the wire shape that the forced-subtag-mode fix depends on.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void SubscribeAlarmsCommand_RoundTripsForcedModeWatchListAndFailover()
|
||||
{
|
||||
var original = new SubscribeAlarmsCommand
|
||||
{
|
||||
SubscriptionExpression = @"\\node\Galaxy!Area",
|
||||
ForcedMode = AlarmProviderMode.Subtag,
|
||||
WatchList =
|
||||
{
|
||||
new AlarmSubtagTarget
|
||||
{
|
||||
AlarmFullReference = "Galaxy!Area.Tank01.Level.HiHi",
|
||||
SourceObjectReference = "Tank01",
|
||||
ActiveSubtag = "Tank01.Level.HiHi.InAlarm",
|
||||
AckedSubtag = "Tank01.Level.HiHi.Acked",
|
||||
AckCommentSubtag = "Tank01.Level.HiHi.AckMsg",
|
||||
PrioritySubtag = "Tank01.Level.HiHi.Priority",
|
||||
},
|
||||
},
|
||||
Failover = new AlarmFailoverConfig
|
||||
{
|
||||
ConsecutiveFailureThreshold = 3,
|
||||
FailbackProbeIntervalSeconds = 10,
|
||||
FailbackStableProbes = 5,
|
||||
},
|
||||
};
|
||||
|
||||
var parsed = SubscribeAlarmsCommand.Parser.ParseFrom(original.ToByteArray());
|
||||
|
||||
Assert.Equal(original, parsed);
|
||||
Assert.Equal(AlarmProviderMode.Subtag, parsed.ForcedMode);
|
||||
var target = Assert.Single(parsed.WatchList);
|
||||
Assert.Equal("Galaxy!Area.Tank01.Level.HiHi", target.AlarmFullReference);
|
||||
Assert.Equal("Tank01", target.SourceObjectReference);
|
||||
Assert.Equal("Tank01.Level.HiHi.InAlarm", target.ActiveSubtag);
|
||||
Assert.Equal("Tank01.Level.HiHi.Acked", target.AckedSubtag);
|
||||
Assert.Equal("Tank01.Level.HiHi.AckMsg", target.AckCommentSubtag);
|
||||
Assert.Equal("Tank01.Level.HiHi.Priority", target.PrioritySubtag);
|
||||
Assert.Equal(3, parsed.Failover.ConsecutiveFailureThreshold);
|
||||
Assert.Equal(10, parsed.Failover.FailbackProbeIntervalSeconds);
|
||||
Assert.Equal(5, parsed.Failover.FailbackStableProbes);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verifies that an <see cref="MxEvent"/> carrying an
|
||||
/// <see cref="OnAlarmProviderModeChangedEvent"/> body (the
|
||||
/// <c>MxEvent.body</c> oneof tag 25 paired with
|
||||
/// <see cref="MxEventFamily.OnAlarmProviderModeChanged"/>, family 6)
|
||||
/// round-trips and resolves to
|
||||
/// <see cref="MxEvent.BodyOneofCase.OnAlarmProviderModeChanged"/>.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void MxEvent_RoundTripsOnAlarmProviderModeChangedBody()
|
||||
{
|
||||
var at = Timestamp.FromDateTime(new DateTime(2026, 6, 13, 9, 30, 0, DateTimeKind.Utc));
|
||||
var original = new MxEvent
|
||||
{
|
||||
Family = MxEventFamily.OnAlarmProviderModeChanged,
|
||||
SessionId = "session-1",
|
||||
WorkerSequence = 42,
|
||||
OnAlarmProviderModeChanged = new OnAlarmProviderModeChangedEvent
|
||||
{
|
||||
Mode = AlarmProviderMode.Subtag,
|
||||
Reason = "wnwrap poll failed 3x",
|
||||
Hresult = unchecked((int)0x80004005),
|
||||
At = at,
|
||||
},
|
||||
};
|
||||
|
||||
var parsed = MxEvent.Parser.ParseFrom(original.ToByteArray());
|
||||
|
||||
Assert.Equal(original, parsed);
|
||||
Assert.Equal(MxEvent.BodyOneofCase.OnAlarmProviderModeChanged, parsed.BodyCase);
|
||||
Assert.Equal(MxEventFamily.OnAlarmProviderModeChanged, parsed.Family);
|
||||
Assert.Equal(AlarmProviderMode.Subtag, parsed.OnAlarmProviderModeChanged.Mode);
|
||||
Assert.Equal(unchecked((int)0x80004005), parsed.OnAlarmProviderModeChanged.Hresult);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user