8a6f0e3c84
Live gate against the cppagent 2.7 fixture: count=16384 with bufferSize
16384 streams; 16385 is OUT_OF_RANGE ('count' must be less than 16385).
Warn only when SampleCount > bufferSize, pin both sides of the edge
against the live Agent, and correct the #804 wording that said 'at or
above'.
130 lines
5.3 KiB
C#
130 lines
5.3 KiB
C#
using System.Net;
|
|
using System.Net.Http;
|
|
using Shouldly;
|
|
using Xunit;
|
|
using ZB.MOM.WW.OtOpcUa.Core.Abstractions;
|
|
|
|
namespace ZB.MOM.WW.OtOpcUa.Driver.MTConnect.Tests;
|
|
|
|
/// <summary>
|
|
/// lmxopcua#825 — a <c>SampleCount</c> above the Agent's <c>bufferSize</c> is refused <c>OUT_OF_RANGE</c> on
|
|
/// every <c>/sample</c> stream. The <c>/probe</c> header carries <c>bufferSize</c>, so Test Connect and the
|
|
/// driver's initialize (deploy) both warn instead of leaving it to surface as a Degraded stream.
|
|
/// </summary>
|
|
[Trait("Category", "Unit")]
|
|
public sealed class MTConnectBufferSizeWarningTests
|
|
{
|
|
private static string ProbeXml(string? bufferSizeAttribute) =>
|
|
$"""
|
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
<MTConnectDevices xmlns="urn:mtconnect.org:MTConnectDevices:2.0">
|
|
<Header instanceId="1"{(bufferSizeAttribute is null ? "" : $" bufferSize=\"{bufferSizeAttribute}\"")}/>
|
|
<Devices>
|
|
<Device id="d" name="D">
|
|
<DataItems><DataItem id="d_avail" category="EVENT" type="AVAILABILITY"/></DataItems>
|
|
</Device>
|
|
</Devices>
|
|
</MTConnectDevices>
|
|
""";
|
|
|
|
[Theory]
|
|
[InlineData("16384", 16384L)]
|
|
[InlineData(null, null)]
|
|
[InlineData("0", null)]
|
|
[InlineData("-5", null)]
|
|
[InlineData("lots", null)]
|
|
public void The_probe_parser_reads_the_header_buffer_size_and_never_fails_on_it(string? attribute, long? expected) =>
|
|
MTConnectProbeParser.Parse(ProbeXml(attribute)).BufferSize.ShouldBe(expected);
|
|
|
|
[Theory]
|
|
[InlineData(16384, 16384L, false)] // live, cppagent 2.7: count == bufferSize is accepted
|
|
[InlineData(16385, 16384L, true)] // ... and bufferSize + 1 refused OUT_OF_RANGE
|
|
[InlineData(20000, 16384L, true)]
|
|
[InlineData(1_000_000, null, false)]
|
|
public void The_warning_fires_only_above_the_buffer_size(int sampleCount, long? bufferSize, bool warns)
|
|
{
|
|
var warning = MTConnectDriver.SampleCountBufferWarning(sampleCount, bufferSize);
|
|
(warning is not null).ShouldBe(warns);
|
|
if (warns) warning!.ShouldContain($"at most {bufferSize}");
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Test_Connect_stays_ok_but_carries_the_warning_when_SampleCount_does_not_fit()
|
|
{
|
|
var probe = new MTConnectDriverProbe(new StubHandler(ProbeXml("16384")));
|
|
var r = await probe.ProbeAsync(
|
|
"{\"agentUri\":\"http://stub-agent:5000\",\"sampleCount\":16385}", TimeSpan.FromSeconds(3),
|
|
TestContext.Current.CancellationToken);
|
|
|
|
r.Ok.ShouldBeTrue("the Agent answered — reachability is not the problem");
|
|
r.Message!.ShouldContain("WARNING:");
|
|
r.Message!.ShouldContain("bufferSize 16384");
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Test_Connect_checks_the_driver_default_when_SampleCount_is_absent()
|
|
{
|
|
// The default SampleCount is 1000 — an Agent with a tiny buffer refuses it too.
|
|
var probe = new MTConnectDriverProbe(new StubHandler(ProbeXml("512")));
|
|
var r = await probe.ProbeAsync(
|
|
"{\"agentUri\":\"http://stub-agent:5000\"}", TimeSpan.FromSeconds(3), TestContext.Current.CancellationToken);
|
|
|
|
r.Ok.ShouldBeTrue();
|
|
r.Message!.ShouldContain("SampleCount 1000 is above the Agent's bufferSize 512");
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Test_Connect_message_is_unchanged_when_SampleCount_fits()
|
|
{
|
|
var probe = new MTConnectDriverProbe(new StubHandler(ProbeXml("16384")));
|
|
var r = await probe.ProbeAsync(
|
|
"{\"agentUri\":\"http://stub-agent:5000\",\"sampleCount\":16384}", TimeSpan.FromSeconds(3),
|
|
TestContext.Current.CancellationToken);
|
|
|
|
r.Ok.ShouldBeTrue();
|
|
r.Message!.ShouldNotContain("WARNING");
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData(131073, true)]
|
|
[InlineData(131072, false)]
|
|
[InlineData(1000, false)]
|
|
public async Task Initialize_warns_and_surfaces_the_buffer_size_on_the_diagnostics_bag(int sampleCount, bool warns)
|
|
{
|
|
var client = CannedAgentClient.FromFixtures(); // Fixtures/probe.xml: bufferSize="131072"
|
|
client.Probe.BufferSize.ShouldBe(131072L);
|
|
var logger = new RecordingDriverLogger();
|
|
var driver = new MTConnectDriver(
|
|
new MTConnectDriverOptions
|
|
{
|
|
AgentUri = "http://fixture-agent:5000",
|
|
RequestTimeoutMs = 5000,
|
|
SampleCount = sampleCount,
|
|
Tags = [new MTConnectTagDefinition("dev1_pos", DriverDataType.Float64)],
|
|
},
|
|
"mt-825",
|
|
_ => client,
|
|
logger);
|
|
try
|
|
{
|
|
await driver.InitializeAsync("{}", TestContext.Current.CancellationToken);
|
|
|
|
logger.Warnings.Any(w => w.Contains("bufferSize", StringComparison.Ordinal)).ShouldBe(warns);
|
|
driver.GetDiagnostics()["agentBufferSize"].ShouldBe("131072");
|
|
}
|
|
finally
|
|
{
|
|
await driver.ShutdownAsync(TestContext.Current.CancellationToken);
|
|
}
|
|
}
|
|
|
|
private sealed class StubHandler(string probeXml) : HttpMessageHandler
|
|
{
|
|
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken ct) =>
|
|
Task.FromResult(new HttpResponseMessage(HttpStatusCode.OK)
|
|
{
|
|
Content = new StringContent(probeXml, System.Text.Encoding.UTF8, "application/xml"),
|
|
});
|
|
}
|
|
}
|