71 lines
3.0 KiB
C#
71 lines
3.0 KiB
C#
using System.Text.Json;
|
|
using Moq;
|
|
using Opc.Ua;
|
|
using Opc.Ua.Client;
|
|
using Shouldly;
|
|
using Xunit;
|
|
using ZB.MOM.WW.OtOpcUa.Core.Abstractions;
|
|
|
|
namespace ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.Tests;
|
|
|
|
/// <summary>
|
|
/// Gitea #764 — the SDK keeps sending publish requests on a session that holds no subscription, and the server
|
|
/// answers each with an anonymous (id 0) <c>BadNoSubscription</c>. With nothing tracked there is nothing to lose,
|
|
/// so those answers must not inflate the <c>publish_error</c> counter. Any other PublishError still counts.
|
|
/// </summary>
|
|
[Trait("Category", "Unit")]
|
|
public sealed class OpcUaClientIdlePublishErrorTests
|
|
{
|
|
private const string SpeedRef = "Plant/dev/Speed";
|
|
private const string AlarmRef = "Plant/dev/TempHi";
|
|
|
|
private static readonly IReadOnlyList<RawTagEntry> Tags =
|
|
[
|
|
new(SpeedRef, JsonSerializer.Serialize(new { nodeId = "ns=0;s=Speed" }), WriteIdempotent: true),
|
|
];
|
|
|
|
private static OpcUaClientDriver NewConnectedDriver(string instance)
|
|
{
|
|
var drv = new OpcUaClientDriver(new OpcUaClientDriverOptions { RawTags = Tags }, instance);
|
|
var session = new Mock<ISession>(MockBehavior.Loose);
|
|
session.SetupGet(s => s.MessageContext).Returns(ServiceMessageContext.Create(SdkTelemetry.Context));
|
|
session.SetupGet(s => s.NamespaceUris).Returns(new NamespaceTable());
|
|
drv.SetSessionForTest(session.Object);
|
|
drv.SetNamespaceMapForTest(NamespaceMap.FromTable(new NamespaceTable(), Tags));
|
|
drv.SetHealthForTest(new DriverHealth(DriverState.Healthy, DateTime.UtcNow, null));
|
|
return drv;
|
|
}
|
|
|
|
[Fact]
|
|
public async Task An_anonymous_BadNoSubscription_on_an_idle_session_is_not_counted()
|
|
{
|
|
var instance = $"opcua-764-{Guid.NewGuid():N}";
|
|
using var cap = new OpcUaClientDiagnosticsTests.Capture(instance);
|
|
var drv = NewConnectedDriver(instance);
|
|
await using var _ = drv;
|
|
|
|
drv.RaisePublishErrorForTest(StatusCodes.BadNoSubscription);
|
|
drv.RaisePublishErrorForTest(StatusCodes.BadNoSubscription);
|
|
cap[OpcUaClientDiagnostics.PublishError].ShouldBe(0, "idle-session publish answers are not errors");
|
|
|
|
// Positive control: any other publish error on the same idle driver still counts.
|
|
drv.RaisePublishErrorForTest(StatusCodes.BadTooManyPublishRequests);
|
|
cap[OpcUaClientDiagnostics.PublishError].ShouldBe(1);
|
|
drv.GetHealth().State.ShouldBe(DriverState.Healthy);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task An_anonymous_BadNoSubscription_with_a_tracked_subscription_is_still_counted()
|
|
{
|
|
var instance = $"opcua-764-{Guid.NewGuid():N}";
|
|
using var cap = new OpcUaClientDiagnosticsTests.Capture(instance);
|
|
var drv = NewConnectedDriver(instance);
|
|
await using var _ = drv;
|
|
drv.AddAlarmSubscriptionForTest([AlarmRef]);
|
|
|
|
drv.RaisePublishErrorForTest(StatusCodes.BadNoSubscription);
|
|
|
|
cap[OpcUaClientDiagnostics.PublishError].ShouldBe(1);
|
|
}
|
|
}
|