using Microsoft.Extensions.Logging; namespace ZB.MOM.WW.OtOpcUa.Driver.MTConnect.Tests; /// /// Captures what the driver logs, so that "and it says so" can be asserted rather than assumed. /// /// /// Used where the log line is the behaviour: a browse scope that matches nothing, and a /// subscription the driver silently refuses to serve. Both are cases whose only other symptom is /// an operator staring at an empty panel, so a fix that emits nothing is not a fix. /// internal sealed class RecordingDriverLogger : ILogger { /// Formatted lines, in order. public List Warnings { get; } = []; /// Formatted lines, in order. public List Errors { get; } = []; /// public IDisposable? BeginScope(TState state) where TState : notnull => null; /// public bool IsEnabled(LogLevel logLevel) => true; /// public void Log( LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func formatter) { ArgumentNullException.ThrowIfNull(formatter); var sink = logLevel switch { LogLevel.Warning => Warnings, LogLevel.Error => Errors, _ => null, }; // Locked: the /sample pump logs from its own task while the test thread reads. if (sink is null) { return; } lock (sink) { sink.Add(formatter(state, exception)); } } /// A snapshot copy of , safe to enumerate while the pump runs. public IReadOnlyList WarningsSnapshot() { lock (Warnings) { return [.. Warnings]; } } }