64e3fbe035
v2-ci / build (push) Failing after 1m43s
v2-ci / unit-tests (tests/Core/ZB.MOM.WW.OtOpcUa.Cluster.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.ControlPlane.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.Runtime.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.Security.Tests) (push) Has been skipped
v2-ci / integration (tests/Server/ZB.MOM.WW.OtOpcUa.Host.IntegrationTests) (push) Has been skipped
v2-ci / integration (tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests) (push) Has been skipped
Adds <summary>, <param>, <typeparam>, and <inheritdoc/> tags to public members surfaced by commentchecker — resolves 5,847 of 5,869 issues (99.6%) across three /fixdocs passes.
80 lines
3.6 KiB
C#
80 lines
3.6 KiB
C#
using Shouldly;
|
||
using Xunit;
|
||
using ZB.MOM.WW.OtOpcUa.Core.Abstractions;
|
||
|
||
namespace ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.Tests;
|
||
|
||
[Trait("Category", "Unit")]
|
||
public sealed class OpcUaClientAlarmTests
|
||
{
|
||
/// <summary>Verifies that MapSeverity buckets per OPC UA Part 9 guidance.</summary>
|
||
/// <param name="opcSev">The OPC UA severity value (1–1000).</param>
|
||
/// <param name="expected">The expected mapped alarm severity.</param>
|
||
[Theory]
|
||
[InlineData((ushort)1, AlarmSeverity.Low)]
|
||
[InlineData((ushort)200, AlarmSeverity.Low)]
|
||
[InlineData((ushort)201, AlarmSeverity.Medium)]
|
||
[InlineData((ushort)500, AlarmSeverity.Medium)]
|
||
[InlineData((ushort)501, AlarmSeverity.High)]
|
||
[InlineData((ushort)800, AlarmSeverity.High)]
|
||
[InlineData((ushort)801, AlarmSeverity.Critical)]
|
||
[InlineData((ushort)1000, AlarmSeverity.Critical)]
|
||
public void MapSeverity_buckets_per_OPC_UA_Part_9_guidance(ushort opcSev, AlarmSeverity expected)
|
||
{
|
||
OpcUaClientDriver.MapSeverity(opcSev).ShouldBe(expected);
|
||
}
|
||
|
||
/// <summary>Verifies that MapSeverity zero maps to Low.</summary>
|
||
[Fact]
|
||
public void MapSeverity_zero_maps_to_Low()
|
||
{
|
||
// 0 isn't in OPC UA's 1-1000 range but we handle it gracefully as Low.
|
||
OpcUaClientDriver.MapSeverity(0).ShouldBe(AlarmSeverity.Low);
|
||
}
|
||
|
||
/// <summary>Verifies that SubscribeAlarmsAsync without initialize throws InvalidOperationException.</summary>
|
||
[Fact]
|
||
public async Task SubscribeAlarmsAsync_without_initialize_throws_InvalidOperationException()
|
||
{
|
||
using var drv = new OpcUaClientDriver(new OpcUaClientDriverOptions(), "opcua-alarm-uninit");
|
||
await Should.ThrowAsync<InvalidOperationException>(async () =>
|
||
await drv.SubscribeAlarmsAsync([], TestContext.Current.CancellationToken));
|
||
}
|
||
|
||
/// <summary>Verifies that UnsubscribeAlarmsAsync with unknown handle is noop.</summary>
|
||
[Fact]
|
||
public async Task UnsubscribeAlarmsAsync_with_unknown_handle_is_noop()
|
||
{
|
||
using var drv = new OpcUaClientDriver(new OpcUaClientDriverOptions(), "opcua-alarm-unknown");
|
||
// Parallels the subscribe handle path — session-drop races shouldn't crash the caller.
|
||
await drv.UnsubscribeAlarmsAsync(new FakeAlarmHandle(), TestContext.Current.CancellationToken);
|
||
}
|
||
|
||
/// <summary>Verifies that AcknowledgeAsync without initialize throws InvalidOperationException.</summary>
|
||
[Fact]
|
||
public async Task AcknowledgeAsync_without_initialize_throws_InvalidOperationException()
|
||
{
|
||
using var drv = new OpcUaClientDriver(new OpcUaClientDriverOptions(), "opcua-ack-uninit");
|
||
await Should.ThrowAsync<InvalidOperationException>(async () =>
|
||
await drv.AcknowledgeAsync(
|
||
[new AlarmAcknowledgeRequest("ns=2;s=Src", "ns=2;s=Cond", "operator ack")],
|
||
TestContext.Current.CancellationToken));
|
||
}
|
||
|
||
/// <summary>Verifies that AcknowledgeAsync with empty batch is noop even without init.</summary>
|
||
[Fact]
|
||
public async Task AcknowledgeAsync_with_empty_batch_is_noop_even_without_init()
|
||
{
|
||
// Empty batch short-circuits before touching the session, so it's safe pre-init. This
|
||
// keeps batch-ack callers from needing to guard the list size themselves.
|
||
using var drv = new OpcUaClientDriver(new OpcUaClientDriverOptions(), "opcua-ack-empty");
|
||
await drv.AcknowledgeAsync([], TestContext.Current.CancellationToken);
|
||
}
|
||
|
||
private sealed class FakeAlarmHandle : IAlarmSubscriptionHandle
|
||
{
|
||
/// <summary>Gets the diagnostic identifier for this alarm handle.</summary>
|
||
public string DiagnosticId => "fake-alarm";
|
||
}
|
||
}
|