using Shouldly; using Xunit; using ZB.MOM.WW.OtOpcUa.Driver.Modbus.IntegrationTests; namespace ZB.MOM.WW.OtOpcUa.Driver.Modbus.IntegrationTests.DL205; /// /// End-to-end smoke against the DL205 ModbusPal profile (or a real DL205 when /// MODBUS_SIM_ENDPOINT points at one). Drives the full /// + real stack — no fake transport. Success proves the /// driver can initialize against the simulator, write a known value, and read it back /// with the correct status and value, which is the baseline every device-quirk test /// builds on. /// /// /// Device-specific quirk tests (word order, max-register, register-zero access, exception /// code translation, etc.) land as separate test classes in this directory as each quirk /// is validated in ModbusPal. Keep this smoke test deliberately narrow — any deviation /// the driver hits beyond "happy-path FC16 + FC03 round-trip" belongs in its own named /// test so filtering by device class (--filter DisplayName~DL205) surfaces the /// quirk-specific failure mode. /// [Collection(ModbusSimulatorCollection.Name)] [Trait("Category", "Integration")] [Trait("Device", "DL205")] public sealed class DL205SmokeTests(ModbusSimulatorFixture sim) { [Fact] public async Task DL205_roundtrip_write_then_read_of_holding_register() { if (sim.SkipReason is not null) Assert.Skip(sim.SkipReason); var options = DL205Profile.BuildOptions(sim.Host, sim.Port); await using var driver = new ModbusDriver(options, driverInstanceId: "dl205-smoke"); await driver.InitializeAsync(driverConfigJson: "{}", TestContext.Current.CancellationToken); // Write first so the test is self-contained — ModbusPal's default register bank is // zeroed at simulator start, and tests must not depend on prior-test state per the // test-plan conventions. var writeResults = await driver.WriteAsync( [new(FullReference: "Smoke_HReg200", Value: (short)DL205Profile.SmokeHoldingValue)], TestContext.Current.CancellationToken); writeResults.Count.ShouldBe(1); writeResults[0].StatusCode.ShouldBe(0u, "write must succeed against the ModbusPal DL205 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)DL205Profile.SmokeHoldingValue); } }