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";
}