using Shouldly; using Xunit; namespace ZB.MOM.WW.OtOpcUa.Driver.Modbus.IntegrationTests.S7; /// /// End-to-end smoke against the S7-1500 MB_SERVER pymodbus profile (or a real /// S7-1500 + MB_SERVER deployment when MODBUS_SIM_ENDPOINT points at one). Drives /// the full + real stack — /// no fake transport. Success proves the driver initializes against the S7 simulator, /// writes a known value, and reads it back with the correct status and value, which is /// the baseline every S7-specific test (PR 57+) builds on. /// /// /// S7-specific quirk tests (MB_SERVER requires non-optimized DBs, ABCD word order /// default, port-per-connection, FC23 Illegal Function, STOP-mode behaviour, etc.) land /// as separate test classes in this directory as each quirk is validated in pymodbus. /// Keep this smoke test deliberately narrow — filtering by device class /// (--filter DisplayName~S7) should surface the quirk-specific failure mode when /// something goes wrong, not a blanket smoke failure that could mean anything. /// [Collection(ModbusSimulatorCollection.Name)] [Trait("Category", "Integration")] [Trait("Device", "S7")] public sealed class S7_1500SmokeTests(ModbusSimulatorFixture sim) { [Fact] public async Task S7_1500_roundtrip_write_then_read_of_holding_register() { if (sim.SkipReason is not null) Assert.Skip(sim.SkipReason); if (!string.Equals(Environment.GetEnvironmentVariable("MODBUS_SIM_PROFILE"), "s7_1500", StringComparison.OrdinalIgnoreCase)) { Assert.Skip("MODBUS_SIM_PROFILE != s7_1500 — skipping (other profiles don't seed the S7 scratch range identically)."); } var options = S7_1500Profile.BuildOptions(sim.Host, sim.Port); await using var driver = new ModbusDriver(options, driverInstanceId: "s7-smoke"); await driver.InitializeAsync(driverConfigJson: "{}", TestContext.Current.CancellationToken); var writeResults = await driver.WriteAsync( [new(FullReference: "Smoke_HReg200", Value: (short)S7_1500Profile.SmokeHoldingValue)], TestContext.Current.CancellationToken); writeResults.Count.ShouldBe(1); writeResults[0].StatusCode.ShouldBe(0u, "write must succeed against the S7-1500 MB_SERVER profile"); var readResults = await driver.ReadAsync( ["Smoke_HReg200"], TestContext.Current.CancellationToken); readResults.Count.ShouldBe(1); readResults[0].StatusCode.ShouldBe(0u); readResults[0].Value.ShouldBe((short)S7_1500Profile.SmokeHoldingValue); } }