test(host): unreachable-directory activation fails bounded; document the SDK impersonation threading contract (03/S2)

This commit is contained in:
Joseph Doherty
2026-07-13 12:00:35 -04:00
parent 0c785415a2
commit 62a49779ac
5 changed files with 81 additions and 1 deletions
@@ -235,6 +235,19 @@ public sealed class OpcUaApplicationHost : IAsyncDisposable
/// the full SDK. Side-effects are confined to mutating <see cref="ImpersonateEventArgs"/>
/// and logging.
/// </summary>
/// <remarks>
/// <b>SDK threading contract (verified against OPCFoundation.NetStandard.Opc.Ua.Server 1.5.378).</b>
/// The SDK raises this handler SYNCHRONOUSLY — it is a plain <c>void</c> delegate, and there is no
/// async impersonation callback in this SDK version. Worse, <c>SessionManager.ActivateSessionAsync</c>
/// invokes it while holding a single <c>SessionManager</c>-wide event lock (<c>m_eventLock</c>), so a
/// handler that blocks does not merely stall one SDK request thread — it SERIALIZES every session
/// activation server-wide (Anonymous and X509 included, since even those paths must take the lock to
/// raise the handler). Consequently the <see cref="IOpcUaUserAuthenticator"/> block-bridge below
/// (<c>GetAwaiter().GetResult()</c> under <see cref="CancellationToken.None"/>) is irreducible: the
/// callback must complete inline. Because the SDK gives no timeout, the hard wall-clock bound + bounded
/// concurrency + directory-outage circuit that keep a slow/hung directory from wedging the SDK live
/// inside the authenticator (<c>LdapOpcUaUserAuthenticator</c>, arch-review 03/S2) — NOT here.
/// </remarks>
/// <param name="authenticator">The user authenticator to validate credentials.</param>
/// <param name="args">The impersonation event arguments to process.</param>
/// <param name="logger">The logger for diagnostic output.</param>
@@ -23,6 +23,9 @@
<ItemGroup>
<InternalsVisibleTo Include="ZB.MOM.WW.OtOpcUa.OpcUaServer.Tests"/>
<!-- R2-08 (03/S2): the outage-sim integration test drives the internal static
OpcUaApplicationHost.HandleImpersonation against the real LDAP library. -->
<InternalsVisibleTo Include="ZB.MOM.WW.OtOpcUa.Host.IntegrationTests"/>
</ItemGroup>
</Project>