test(ldap): env-gated failover integration test vs live GLAuth
This commit is contained in:
@@ -99,4 +99,70 @@ public sealed class GLAuthIntegrationTests
|
||||
$"Authentication failed: {result.Failure} (server={server}:{port}, user={user})");
|
||||
Assert.NotEmpty(result.Groups);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Failover: primary endpoint points at a closed local port (refused immediately),
|
||||
/// fallback at the real GLAuth. The login must succeed via the fallback, and a second
|
||||
/// login must also succeed (sticky preference — no re-walk through the dead primary).
|
||||
/// Skipped unless <c>ZB_LDAP_IT=1</c> is set; skipped again if the server is unreachable.
|
||||
/// </summary>
|
||||
[SkippableFact]
|
||||
public async Task Authenticate_FailsOverFromDeadPrimary_ToRealGLAuth()
|
||||
{
|
||||
// ------------------------------------------------------------------ opt-in gate
|
||||
Skip.IfNot(
|
||||
Environment.GetEnvironmentVariable("ZB_LDAP_IT") == "1",
|
||||
"Set ZB_LDAP_IT=1 and a reachable GLAuth to run.");
|
||||
|
||||
// ------------------------------------------------------------------ read config
|
||||
var server = Environment.GetEnvironmentVariable("ZB_LDAP_SERVER") ?? "localhost";
|
||||
var port = int.TryParse(Environment.GetEnvironmentVariable("ZB_LDAP_PORT"), out var p) ? p : 3893;
|
||||
var baseDn = Environment.GetEnvironmentVariable("ZB_LDAP_BASE") ?? "dc=lmxopcua,dc=local";
|
||||
var svcDn = Environment.GetEnvironmentVariable("ZB_LDAP_SVC_DN") ?? "";
|
||||
var svcPw = Environment.GetEnvironmentVariable("ZB_LDAP_SVC_PW") ?? "";
|
||||
var user = Environment.GetEnvironmentVariable("ZB_LDAP_USER") ?? "";
|
||||
var pw = Environment.GetEnvironmentVariable("ZB_LDAP_PW") ?? "";
|
||||
var userAttr = Environment.GetEnvironmentVariable("ZB_LDAP_USERATTR") ?? "cn";
|
||||
|
||||
// ------------------------------------------------------------------ reachability probe
|
||||
try
|
||||
{
|
||||
using var tcp = new TcpClient();
|
||||
// 3-second connect timeout to keep the test suite snappy when the server is absent
|
||||
var connectTask = tcp.ConnectAsync(server, port);
|
||||
if (!connectTask.Wait(TimeSpan.FromSeconds(3)))
|
||||
Skip.If(true, $"GLAuth not reachable at {server}:{port} (connect timed out).");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Skip.If(true, $"GLAuth not reachable at {server}:{port}: {ex.Message}");
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------ build options
|
||||
var options = new LdapOptions
|
||||
{
|
||||
Enabled = true,
|
||||
Server = "127.0.0.1",
|
||||
Port = 39999, // closed port -> immediate refusal
|
||||
Transport = LdapTransport.None,
|
||||
AllowInsecure = true,
|
||||
SearchBase = baseDn,
|
||||
ServiceAccountDn = svcDn,
|
||||
ServiceAccountPassword = svcPw,
|
||||
UserNameAttribute = userAttr,
|
||||
GroupAttribute = "memberOf",
|
||||
ConnectionTimeoutMs = 3000,
|
||||
FallbackServers = new[] { $"{server}:{port}" },
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------ exercise the real service
|
||||
var svc = new LdapAuthService(options);
|
||||
|
||||
var first = await svc.AuthenticateAsync(user, pw, CancellationToken.None);
|
||||
Assert.True(first.Succeeded, $"first login failed: {first.Failure}");
|
||||
|
||||
// Second login exercises the sticky preference: it must not re-walk the dead primary.
|
||||
var second = await svc.AuthenticateAsync(user, pw, CancellationToken.None);
|
||||
Assert.True(second.Succeeded, $"second login failed: {second.Failure}");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user