Add OPC UA array element write integration test

This commit is contained in:
Joseph Doherty
2026-03-25 11:05:04 -04:00
parent 4351854754
commit 3f813b3869
4 changed files with 134 additions and 1 deletions

View File

@@ -55,6 +55,8 @@ namespace ZB.MOM.WW.LmxOpcUa.Tests.Helpers
public Task<bool> WriteAsync(string fullTagReference, object value, CancellationToken ct = default)
{
WrittenValues.Add((fullTagReference, value));
if (WriteResult)
TagValues[fullTagReference] = Vtq.Good(value);
return Task.FromResult(WriteResult);
}

View File

@@ -114,6 +114,27 @@ namespace ZB.MOM.WW.LmxOpcUa.Tests.Helpers
return Session.ReadValue(nodeId);
}
/// <summary>
/// Write a node's value, optionally using an OPC UA index range for array element writes.
/// Returns the server status code for the write.
/// </summary>
public StatusCode Write(NodeId nodeId, object value, string? indexRange = null)
{
var nodesToWrite = new WriteValueCollection
{
new WriteValue
{
NodeId = nodeId,
AttributeId = Attributes.Value,
IndexRange = indexRange,
Value = new DataValue(new Variant(value))
}
};
Session.Write(null, nodesToWrite, out var results, out _);
return results[0];
}
/// <summary>
/// Create a subscription with a monitored item on the given node.
/// Returns the subscription and monitored item for inspection.

View File

@@ -0,0 +1,50 @@
using System.Linq;
using System.Threading.Tasks;
using Opc.Ua;
using Shouldly;
using Xunit;
using ZB.MOM.WW.LmxOpcUa.Host.Domain;
using ZB.MOM.WW.LmxOpcUa.Tests.Helpers;
namespace ZB.MOM.WW.LmxOpcUa.Tests.Integration
{
public class ArrayWriteTests
{
[Fact]
public async Task Write_SingleArrayElement_UpdatesWholeArrayValue()
{
var fixture = OpcUaServerFixture.WithFakeMxAccessClient();
fixture.MxAccessClient!.TagValues["MESReceiver_001.MoveInPartNumbers[]"] = Vtq.Good(
Enumerable.Range(0, 50).Select(i => $"PART-{i:00}").ToArray());
await fixture.InitializeAsync();
try
{
using var client = new OpcUaTestClient();
await client.ConnectAsync(fixture.EndpointUrl);
// Browse path: TestMachine_001 -> MESReceiver -> MoveInPartNumbers
var nodeId = client.MakeNodeId("MESReceiver_001.MoveInPartNumbers[]");
var before = client.Read(nodeId).Value as string[];
before.ShouldNotBeNull();
before.Length.ShouldBe(50);
before[1].ShouldBe("PART-01");
var status = client.Write(nodeId, new[] { "UPDATED-PART" }, indexRange: "1");
StatusCode.IsGood(status).ShouldBe(true);
var after = client.Read(nodeId).Value as string[];
after.ShouldNotBeNull();
after.Length.ShouldBe(50);
after[0].ShouldBe("PART-00");
after[1].ShouldBe("UPDATED-PART");
after[2].ShouldBe("PART-02");
}
finally
{
await fixture.DisposeAsync();
}
}
}
}