using Opc.Ua; using ZB.MOM.WW.OtOpcUa.Client.Shared.Adapters; namespace ZB.MOM.WW.OtOpcUa.Client.Shared.Tests.Fakes; internal sealed class FakeSessionFactory : ISessionFactory { private readonly List _createdSessions = []; private readonly Queue _sessions = new(); /// Gets the number of times CreateSessionAsync has been called. public int CreateCallCount { get; private set; } /// Gets or sets a value indicating whether CreateSessionAsync should throw. public bool ThrowOnCreate { get; set; } /// Gets the endpoint URL from the last CreateSessionAsync call. public string? LastEndpointUrl { get; private set; } /// /// Optional gate that, when set, blocks until completed. /// Lets tests hold a failover loop in-flight to exercise re-entrancy. /// public TaskCompletionSource? CreateGate { get; set; } /// Gets the list of sessions created via CreateSessionAsync. public IReadOnlyList CreatedSessions => _createdSessions; /// Creates a session asynchronously (fake implementation). /// The application configuration. /// The endpoint description. /// The session name. /// The session timeout in milliseconds. /// The user identity. /// Cancellation token. /// A task containing the session adapter. public async Task CreateSessionAsync( ApplicationConfiguration config, EndpointDescription endpoint, string sessionName, uint sessionTimeoutMs, UserIdentity identity, CancellationToken ct) { CreateCallCount++; LastEndpointUrl = endpoint.EndpointUrl; if (CreateGate != null) await CreateGate.Task; if (ThrowOnCreate) throw new InvalidOperationException("FakeSessionFactory configured to fail."); FakeSessionAdapter session; if (_sessions.Count > 0) session = _sessions.Dequeue(); else session = new FakeSessionAdapter { EndpointUrl = endpoint.EndpointUrl, ServerName = endpoint.Server?.ApplicationName?.Text ?? "FakeServer", SecurityMode = endpoint.SecurityMode.ToString(), SecurityPolicyUri = endpoint.SecurityPolicyUri ?? string.Empty }; // Ensure endpoint URL matches session.EndpointUrl = endpoint.EndpointUrl; _createdSessions.Add(session); return session; } /// /// Enqueues a session adapter to be returned on the next call to CreateSessionAsync. /// /// The session adapter to enqueue. public void EnqueueSession(FakeSessionAdapter session) { _sessions.Enqueue(session); } }