b0b0ce9c77
Claude-Session: https://claude.ai/code/session_01Ef2ozxS7QPanGT8uoATbTe
56 lines
2.8 KiB
C#
56 lines
2.8 KiB
C#
using Shouldly;
|
|
using Xunit;
|
|
using ZB.MOM.WW.OtOpcUa.Core.Abstractions;
|
|
using ZB.MOM.WW.OtOpcUa.Driver.AbLegacy.PlcFamilies;
|
|
|
|
namespace ZB.MOM.WW.OtOpcUa.Driver.AbLegacy.IntegrationTests;
|
|
|
|
/// <summary>
|
|
/// #646 against <c>ab_server</c>: <c>N7:[N7:0]</c> reads the index word, then the word it names, on both
|
|
/// transports. Writes N7:0 and N7:5 (simulator-only, gated by <see cref="IntegrationWriteGate"/>).
|
|
/// </summary>
|
|
[Collection(AbLegacyServerCollection.Name)]
|
|
[Trait("Category", "Integration")]
|
|
[Trait("Simulator", "ab_server-PCCC")]
|
|
public sealed class AbLegacyIndirectAddressingTests(AbLegacyServerFixture sim)
|
|
{
|
|
/// <summary>Seeds N7:0=5 and N7:5=42, then reads and writes through <c>N7:[N7:0]</c>.</summary>
|
|
/// <param name="transport">The transport stack the driver runs on.</param>
|
|
[AbLegacyTheory]
|
|
[MemberData(nameof(TransportMatrix.Transports), MemberType = typeof(TransportMatrix))]
|
|
public async Task Slc500_indirect_word_read_and_write_resolve_through_the_index(AbLegacyTransport transport)
|
|
{
|
|
if (sim.SkipReasonFor(KnownProfiles.Slc500) is { } skip) Assert.Skip(skip);
|
|
IntegrationWriteGate.SkipUnlessWritesAllowed();
|
|
|
|
var deviceUri = $"ab://{sim.Host}:{sim.PortFor(KnownProfiles.Slc500)}/{sim.CipPath}";
|
|
await using var drv = new AbLegacyDriver(new AbLegacyDriverOptions
|
|
{
|
|
Devices = [new AbLegacyDeviceOptions(deviceUri, AbLegacyPlcFamily.Slc500)],
|
|
RawTags = AbLegacyRawTags.Entries(
|
|
new AbLegacyTagDefinition("Index", deviceUri, "N7:0", AbLegacyDataType.Int, Writable: true),
|
|
new AbLegacyTagDefinition("Target", deviceUri, "N7:5", AbLegacyDataType.Int, Writable: true),
|
|
new AbLegacyTagDefinition("Indirect", deviceUri, "N7:[N7:0]", AbLegacyDataType.Int, Writable: true)),
|
|
Timeout = TimeSpan.FromSeconds(5),
|
|
Probe = new AbLegacyProbeOptions { Enabled = false },
|
|
Transport = transport,
|
|
}, driverInstanceId: $"ablegacy-indirect-{transport}");
|
|
var ct = TestContext.Current.CancellationToken;
|
|
await drv.InitializeAsync("{}", ct);
|
|
|
|
var seeded = await drv.WriteAsync(
|
|
[new WriteRequest("Index", (short)5), new WriteRequest("Target", (short)42)], ct);
|
|
seeded.ShouldAllBe(r => r.StatusCode == AbLegacyStatusMapper.Good);
|
|
|
|
var read = (await drv.ReadAsync(["Indirect"], ct)).Single();
|
|
read.StatusCode.ShouldBe(AbLegacyStatusMapper.Good);
|
|
Convert.ToInt32(read.Value).ShouldBe(42);
|
|
|
|
// Write through the indirection lands on N7:5.
|
|
(await drv.WriteAsync([new WriteRequest("Indirect", (short)77)], ct)).Single()
|
|
.StatusCode.ShouldBe(AbLegacyStatusMapper.Good);
|
|
var direct = (await drv.ReadAsync(["Target"], ct)).Single();
|
|
Convert.ToInt32(direct.Value).ShouldBe(77);
|
|
}
|
|
}
|