57 lines
2.6 KiB
C#
57 lines
2.6 KiB
C#
namespace ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.IntegrationTests;
|
|
|
|
/// <summary>
|
|
/// Fixture for the reverse-connect variant of opc-plc (PR-11). Unlike the
|
|
/// dial-mode <see cref="OpcPlcFixture"/>, the simulator here is the dialer:
|
|
/// it reaches OUT to the test runner's listener URL on
|
|
/// <c>opc.tcp://host.docker.internal:4844</c>. 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.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// <para>
|
|
/// <b>Why no port-probe</b>: 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 <see cref="SkipReason"/>
|
|
/// which is set from the <c>OPCUA_RC_SIM</c> env var (any value =
|
|
/// "simulator running"; absent = skip).
|
|
/// </para>
|
|
/// <para>
|
|
/// The "shared listener URL" model is enforced by the driver's
|
|
/// <c>ReverseConnectListener</c> singleton — multiple smoke tests in the
|
|
/// same xunit assembly share one listener instance even if they run in
|
|
/// parallel. Tests should pick distinct <c>ExpectedServerUri</c> values to
|
|
/// demultiplex inbound connections.
|
|
/// </para>
|
|
/// </remarks>
|
|
public sealed class OpcPlcReverseConnectFixture : IAsyncDisposable
|
|
{
|
|
private const string DefaultListenerUrl = "opc.tcp://0.0.0.0:4844";
|
|
private const string EnvVar = "OPCUA_RC_SIM";
|
|
|
|
/// <summary>The listener URL the driver should bind for incoming reverse-connect dials.</summary>
|
|
public string ListenerUrl { get; } = DefaultListenerUrl;
|
|
|
|
/// <summary>Skip reason when the reverse-connect simulator isn't available; null when ready.</summary>
|
|
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<OpcPlcReverseConnectFixture>
|
|
{
|
|
public const string Name = "OpcPlcReverseConnect";
|
|
}
|