namespace ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.IntegrationTests; /// /// Fixture for the reverse-connect variant of opc-plc (PR-11). Unlike the /// dial-mode , the simulator here is the dialer: /// it reaches OUT to the test runner's listener URL on /// opc.tcp://host.docker.internal:4844. The fixture's job is to /// advertise the listener URL the test should bind and provide a clear /// skip reason when the docker-compose service isn't running. /// /// /// /// Why no port-probe: the conventional fixture probes the simulator's /// server port to detect docker-up. In reverse-connect the simulator opens /// no inbound port — it's a pure dialer — so a probe would always fail. /// Tests that want a hard skip should look at /// which is set from the OPCUA_RC_SIM env var (any value = /// "simulator running"; absent = skip). /// /// /// The "shared listener URL" model is enforced by the driver's /// ReverseConnectListener singleton — multiple smoke tests in the /// same xunit assembly share one listener instance even if they run in /// parallel. Tests should pick distinct ExpectedServerUri values to /// demultiplex inbound connections. /// /// public sealed class OpcPlcReverseConnectFixture : IAsyncDisposable { private const string DefaultListenerUrl = "opc.tcp://0.0.0.0:4844"; private const string EnvVar = "OPCUA_RC_SIM"; /// The listener URL the driver should bind for incoming reverse-connect dials. public string ListenerUrl { get; } = DefaultListenerUrl; /// Skip reason when the reverse-connect simulator isn't available; null when ready. public string? SkipReason { get; } public OpcPlcReverseConnectFixture() { if (string.IsNullOrWhiteSpace(Environment.GetEnvironmentVariable(EnvVar))) { SkipReason = $"Reverse-connect smoke skipped — set {EnvVar}=1 once `docker compose -f Docker/docker-compose.yml up opc-plc-rc` is healthy. " + "The dialer needs host.docker.internal to reach this machine — verify Docker Desktop's network mode supports it."; } } public ValueTask DisposeAsync() => ValueTask.CompletedTask; } [Xunit.CollectionDefinition(Name)] public sealed class OpcPlcReverseConnectCollection : Xunit.ICollectionFixture { public const string Name = "OpcPlcReverseConnect"; }