e77bca385a
- Galaxy: deadline bounds the wait, not the subscribe RPC; BadTimeout for all tags and late handles unsubscribed; doc comment relocated - S7: probe connect runs on the connect deadline so a timeout opens the backoff window - S7: a successful write only retires a Faulted the write side owns - S7: null array elements rejected (BadTypeMismatch); multi-PDU array writes documented non-atomic - S7 integration: array write test gated on S7_SIM_ALLOW_WRITES=1 Claude-Session: https://claude.ai/code/session_01Ef2ozxS7QPanGT8uoATbTe
57 lines
2.5 KiB
C#
57 lines
2.5 KiB
C#
using Shouldly;
|
|
using Xunit;
|
|
using ZB.MOM.WW.OtOpcUa.Core.Abstractions;
|
|
|
|
namespace ZB.MOM.WW.OtOpcUa.Driver.S7.IntegrationTests.S7_1500;
|
|
|
|
/// <summary>
|
|
/// #610 item 2 (S7-016): array write round trip against the python-snap7 S7-1500 profile. Skips
|
|
/// cleanly when the sim is absent. Uses DB1 bytes 700+ (the profile's 1024-byte DB1 has no seed
|
|
/// there), so the writes cannot disturb another test's seeds. Writes also require
|
|
/// <c>S7_SIM_ALLOW_WRITES=1</c>.
|
|
/// </summary>
|
|
[Collection(Snap7ServerCollection.Name)]
|
|
[Trait("Category", "Integration")]
|
|
[Trait("Device", "S7_1500")]
|
|
public sealed class S7_1500ArrayWriteTests(Snap7ServerFixture sim)
|
|
{
|
|
private static S7DriverOptions Options(string host, int port) => new()
|
|
{
|
|
Host = host,
|
|
Port = port,
|
|
CpuType = S7CpuType.S71500,
|
|
Rack = 0,
|
|
Slot = 0,
|
|
Timeout = TimeSpan.FromSeconds(5),
|
|
Probe = new S7ProbeOptions { Enabled = false },
|
|
RawTags = S7RawTags.Entries(
|
|
new S7TagDefinition("I16Arr", "DB1.DBW700", S7DataType.Int16, Writable: true, ArrayCount: 4),
|
|
new S7TagDefinition("F32Arr", "DB1.DBD720", S7DataType.Float32, Writable: true, ArrayCount: 3)),
|
|
};
|
|
|
|
/// <summary>Writes a non-trivial Int16[4] and Float32[3], then reads each back element-for-element.</summary>
|
|
[Fact]
|
|
public async Task Array_write_then_read_round_trips_through_real_S7comm()
|
|
{
|
|
if (sim.SkipReason is not null) Assert.Skip(sim.SkipReason);
|
|
// S7_SIM_ENDPOINT may point at a real CPU; writing needs an explicit opt-in (simulator runs only).
|
|
if (Environment.GetEnvironmentVariable("S7_SIM_ALLOW_WRITES") != "1")
|
|
Assert.Skip("Write test: set S7_SIM_ALLOW_WRITES=1 to allow writes to the endpoint under test (simulator only).");
|
|
|
|
await using var drv = new S7Driver(Options(sim.Host, sim.Port), "s7-arr-write");
|
|
await drv.InitializeAsync("{}", TestContext.Current.CancellationToken);
|
|
|
|
var i16 = new short[] { 111, -222, 3333, -4444 };
|
|
var f32 = new[] { 1.5f, -2.25f, 1234.5f };
|
|
var res = await drv.WriteAsync(
|
|
[new WriteRequest("I16Arr", i16), new WriteRequest("F32Arr", f32)],
|
|
TestContext.Current.CancellationToken);
|
|
res.Select(r => r.StatusCode).ShouldAllBe(c => c == 0u);
|
|
|
|
var read = await drv.ReadAsync(["I16Arr", "F32Arr"], TestContext.Current.CancellationToken);
|
|
read.Select(r => r.StatusCode).ShouldAllBe(c => c == 0u);
|
|
((short[])read[0].Value!).ShouldBe(i16);
|
|
((float[])read[1].Value!).ShouldBe(f32);
|
|
}
|
|
}
|