using Microsoft.Extensions.Logging; using Shouldly; using Xunit; namespace ZB.MOM.WW.OtOpcUa.Driver.AbCip.Tests; /// /// The transport the instance runs on is logged at every init through the HOST-supplied logger factory, /// so an operator can tell from the node log which stack serves a driver (T19 live gate). The factory /// path is the one under test: a driver built without a logger writes to the null logger. /// [Trait("Category", "Unit")] public sealed class AbCipTransportInitLogTests { private static string Config(string? transport) => $$"""{{{(transport is null ? "" : $"\"transport\":\"{transport}\",")}}"probe":{"enabled":false},"devices":[{"hostAddress":"ab://10.0.0.1:44818/1,0","plcFamily":"ControlLogix"}]}"""; /// The init line names the configured-vs-effective transport (Task 22). [Theory] [InlineData("Native", "Native (configured)")] [InlineData("Libplctag", "Libplctag (configured)")] [InlineData(null, "Native (default)")] public async Task Init_logs_the_transport_through_the_registered_logger_factory(string? json, string expected) { var captured = new List(); using var factory = new CapturingLoggerFactory(captured); var driver = AbCipDriverFactoryExtensions.CreateInstance("drv-t19", Config(json), factory); try { await driver.InitializeAsync(Config(json), TestContext.Current.CancellationToken); } finally { await driver.ShutdownAsync(TestContext.Current.CancellationToken); } captured.ShouldContain(m => m.Contains("drv-t19") && m.Contains($"transport={expected}")); } private sealed class CapturingLoggerFactory(List sink) : ILoggerFactory { public ILogger CreateLogger(string categoryName) => new CapturingLogger(sink); public void AddProvider(ILoggerProvider provider) { } public void Dispose() { } } private sealed class CapturingLogger(List sink) : ILogger { 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) { lock (sink) sink.Add(formatter(state, exception)); } } }