using Shouldly; using Xunit; using ZB.MOM.WW.OtOpcUa.Core.Abstractions; using ZB.MOM.WW.OtOpcUa.Driver.AbCip; namespace ZB.MOM.WW.OtOpcUa.Driver.AbCip.IntegrationTests; /// /// End-to-end smoke tests that exercise the real libplctag stack against a running /// ab_server. Skipped when the binary isn't on PATH (). /// /// /// Intentionally minimal — per-family + per-capability coverage ships in PRs 9–12 once the /// integration harness is CI-ready. This file exists at PR 3 time to prove the wire path /// works end-to-end on developer boxes that have ab_server. /// [Trait("Category", "Integration")] [Trait("Requires", "AbServer")] public sealed class AbCipReadSmokeTests : IAsyncLifetime { private readonly AbServerFixture _fixture = new(); public async ValueTask InitializeAsync() => await _fixture.InitializeAsync(); public async ValueTask DisposeAsync() => await _fixture.DisposeAsync(); [AbServerFact] public async Task Driver_reads_DInt_from_ab_server() { var drv = new AbCipDriver(new AbCipDriverOptions { Devices = [new AbCipDeviceOptions($"ab://127.0.0.1:{_fixture.Port}/1,0", AbCipPlcFamily.ControlLogix)], Tags = [new AbCipTagDefinition("Counter", $"ab://127.0.0.1:{_fixture.Port}/1,0", "TestDINT", AbCipDataType.DInt)], Timeout = TimeSpan.FromSeconds(5), }, "drv-smoke"); await drv.InitializeAsync("{}", CancellationToken.None); var snapshots = await drv.ReadAsync(["Counter"], CancellationToken.None); snapshots.Single().StatusCode.ShouldBe(AbCipStatusMapper.Good); drv.GetHealth().State.ShouldBe(DriverState.Healthy); await drv.ShutdownAsync(CancellationToken.None); } }