Files
lmxopcua/tests/Server/ZB.MOM.WW.OtOpcUa.Host.IntegrationTests/DockerFixtureAvailability.cs
T
Joseph Doherty 494da22cd1 test(adminui): E2E scaffolding for Test Connect + Reconnect + Status hub
- DriverTestConnectE2eTests: 3 scenarios (sim/wrong-port/black-hole)
  against the Modbus Docker fixture. Sim + wrong-port skip if fixture
  unreachable; black-hole uses ModbusDriverProbe directly (no fixture).
- DriverReconnectE2eTests: message round-trip through AdminOperationsActor
  cluster singleton — Ok=true + audit write, without live driver side effect.
- DriverStatusHubE2eTests: bridge-mocked fallback — spawns
  DriverStatusSignalRBridge in the harness ActorSystem with a mock
  IHubContext, publishes DriverHealthChanged to the driver-health DPS
  topic, asserts store upsert + hub SendAsync call.
- DockerFixtureAvailability helper: TCP-connect probe for skip guards.
- Moq 4.20.72 added to central package management for hub mocking.
- Design doc §8.3 replaced with concrete pre-ship operator runbook.
2026-05-28 11:31:12 -04:00

61 lines
2.4 KiB
C#

using System.Net.Sockets;
namespace ZB.MOM.WW.OtOpcUa.Host.IntegrationTests;
/// <summary>
/// Lightweight TCP-connect probe used by E2E integration tests to detect whether a Docker
/// fixture is reachable before attempting live work. Tests skip cleanly when this returns
/// <c>false</c>; CI with fixtures available lets them run.
/// </summary>
public static class DockerFixtureAvailability
{
/// <summary>
/// Attempts a TCP connect to <paramref name="host"/>:<paramref name="port"/>. Returns
/// <c>true</c> if the connection is accepted within <paramref name="timeoutMs"/>
/// milliseconds; <c>false</c> on refusal, timeout, or DNS failure.
/// </summary>
/// <param name="host">The host to probe.</param>
/// <param name="port">The TCP port to connect to.</param>
/// <param name="timeoutMs">Maximum time to wait in milliseconds; defaults to 500.</param>
public static bool IsReachable(string host, int port, int timeoutMs = 500)
{
try
{
// Force IPv4 — remote Docker host binds only on IPv4 (0.0.0.0).
using var client = new TcpClient(AddressFamily.InterNetwork);
var ipv4 = System.Net.Dns.GetHostAddresses(host)
.FirstOrDefault(a => a.AddressFamily == AddressFamily.InterNetwork)
?? System.Net.IPAddress.Parse(host);
var task = client.ConnectAsync(ipv4, port);
return task.Wait(timeoutMs) && client.Connected;
}
catch
{
return false;
}
}
/// <summary>
/// Parses an <c>HOST:PORT</c> endpoint string and probes reachability.
/// Returns <c>true</c> if the connection succeeds within <paramref name="timeoutMs"/>
/// milliseconds. Handles malformed strings gracefully by returning <c>false</c>.
/// </summary>
/// <param name="endpoint">Endpoint in <c>host:port</c> format.</param>
/// <param name="timeoutMs">Maximum time to wait in milliseconds; defaults to 500.</param>
public static bool IsReachable(string endpoint, int timeoutMs = 500)
{
try
{
var parts = endpoint.Split(':', 2);
if (parts.Length != 2 || !int.TryParse(parts[1], out var port))
return false;
return IsReachable(parts[0], port, timeoutMs);
}
catch
{
return false;
}
}
}