Files
lmxopcua/tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.Tests/HistoryServerCapabilitiesAdvertisementTests.cs
T

59 lines
2.5 KiB
C#

using Opc.Ua;
using Opc.Ua.Server;
using Shouldly;
using Xunit;
namespace ZB.MOM.WW.OtOpcUa.OpcUaServer.Tests;
/// <summary>
/// R08:1.1 (#736): the server raw cap (<c>ServerHistorian:MaxRawValuesPerRead</c>) is advertised as
/// <c>HistoryServerCapabilities/MaxReturnDataValues</c> (i=11273) through <see cref="HistoryPaging.AdvertiseMaxReturnDataValues"/>,
/// read back the way a client would — through the SDK master node manager — over a real server.
/// </summary>
public sealed class HistoryServerCapabilitiesAdvertisementTests(BoundsServerFixture fx) : IClassFixture<BoundsServerFixture>
{
private async Task<uint> ReadAdvertisedAsync()
{
var context = new OperationContext(new RequestHeader(), secureChannelContext: null, RequestType.Read, requestLifetime: RequestLifetime.None, identity: null);
var nodesToRead = new List<ReadValueId>
{
new ReadValueId { NodeId = VariableIds.HistoryServerCapabilities_MaxReturnDataValues, AttributeId = Attributes.Value },
};
var (values, _) = await fx.Nm.Server.NodeManager.ReadAsync(context, 0, TimestampsToReturn.Neither, nodesToRead, TestContext.Current.CancellationToken);
values.Count.ShouldBe(1);
StatusCode.IsGood(values[0].StatusCode).ShouldBeTrue(values[0].StatusCode.ToString());
return (uint)SdkValueBoundary.ToClr(values[0].WrappedValue)!;
}
[Fact]
public async Task The_cap_is_advertised_as_MaxReturnDataValues_and_a_re_sync_overwrites_it()
{
await fx.Gate.WaitAsync(TestContext.Current.CancellationToken);
try
{
HistoryPaging.AdvertiseMaxReturnDataValues(fx.Nm.Server, 10_000).ShouldBeTrue();
(await ReadAdvertisedAsync()).ShouldBe(10_000u);
HistoryPaging.AdvertiseMaxReturnDataValues(fx.Nm.Server, 2_500).ShouldBeTrue();
(await ReadAdvertisedAsync()).ShouldBe(2_500u);
// Unbounded (the opt-out) advertises Part 11's "no limit".
HistoryPaging.AdvertiseMaxReturnDataValues(fx.Nm.Server, 0).ShouldBeTrue();
(await ReadAdvertisedAsync()).ShouldBe(0u);
HistoryPaging.AdvertiseMaxReturnDataValues(fx.Nm.Server, -5).ShouldBeTrue();
(await ReadAdvertisedAsync()).ShouldBe(0u);
}
finally
{
HistoryPaging.AdvertiseMaxReturnDataValues(fx.Nm.Server, 0);
fx.Gate.Release();
}
}
[Fact]
public void No_server_is_a_quiet_false()
{
HistoryPaging.AdvertiseMaxReturnDataValues(null, 10_000).ShouldBeFalse();
}
}