Skip to content
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using Microsoft.Testing.Platform.Extensions;
using Microsoft.Testing.Platform.Helpers;
using Microsoft.Testing.Platform.Logging;

using Moq;

namespace Microsoft.Testing.Platform.UnitTests;

[TestClass]
public sealed class LoggingManagerTests
{
private readonly Mock<IMonitor> _mockMonitor = new();
private readonly Mock<IServiceProvider> _mockServiceProvider = new();

public LoggingManagerTests()
=> _mockMonitor.Setup(p => p.Lock(It.IsAny<object>())).Returns(new Mock<IDisposable>().Object);

[TestMethod]
public void AddProvider_NullFactory_ThrowsArgumentNullException()
{
LoggingManager manager = new();
Assert.ThrowsExactly<ArgumentNullException>(() => manager.AddProvider(null!));
}

[TestMethod]
public async Task BuildAsync_NoProviders_ReturnsNonNullFactory()
{
LoggingManager manager = new();
ILoggerFactory factory = await manager.BuildAsync(_mockServiceProvider.Object, LogLevel.Information, _mockMonitor.Object);
Assert.IsNotNull(factory);
}

[TestMethod]
public async Task BuildAsync_PassesCorrectLogLevelAndServiceProviderToFactory()
{
LogLevel capturedLevel = default;
IServiceProvider? capturedServiceProvider = null;

LoggingManager manager = new();
Mock<ILoggerProvider> mockProvider = new();
mockProvider.Setup(p => p.CreateLogger(It.IsAny<string>())).Returns(new Mock<ILogger>().Object);

manager.AddProvider((level, sp) =>
{
capturedLevel = level;
capturedServiceProvider = sp;
return mockProvider.Object;
});

await manager.BuildAsync(_mockServiceProvider.Object, LogLevel.Warning, _mockMonitor.Object);

Assert.AreEqual(LogLevel.Warning, capturedLevel);
Assert.AreSame(_mockServiceProvider.Object, capturedServiceProvider);
}

[TestMethod]
public async Task BuildAsync_NonExtensionProvider_IsAlwaysIncluded()
{
LoggingManager manager = new();
Mock<ILoggerProvider> mockProvider = new();
mockProvider.Setup(p => p.CreateLogger(It.IsAny<string>())).Returns(new Mock<ILogger>().Object);
manager.AddProvider((_, _) => mockProvider.Object);

ILoggerFactory factory = await manager.BuildAsync(_mockServiceProvider.Object, LogLevel.Information, _mockMonitor.Object);
_ = factory.CreateLogger("test");

mockProvider.Verify(p => p.CreateLogger("test"), Times.Once);
}

[TestMethod]
public async Task BuildAsync_EnabledExtensionProvider_IsIncluded()
{
LoggingManager manager = new();
Mock<IExtensionLoggerProvider> mockProvider = new();
mockProvider.Setup(p => p.IsEnabledAsync()).ReturnsAsync(true);
mockProvider.Setup(p => p.CreateLogger(It.IsAny<string>())).Returns(new Mock<ILogger>().Object);
manager.AddProvider((_, _) => mockProvider.Object);

ILoggerFactory factory = await manager.BuildAsync(_mockServiceProvider.Object, LogLevel.Information, _mockMonitor.Object);
_ = factory.CreateLogger("test");

mockProvider.Verify(p => p.CreateLogger("test"), Times.Once);
}

[TestMethod]
public async Task BuildAsync_DisabledExtensionProvider_IsExcluded()
{
LoggingManager manager = new();
Mock<IExtensionLoggerProvider> mockProvider = new();
mockProvider.Setup(p => p.IsEnabledAsync()).ReturnsAsync(false);
manager.AddProvider((_, _) => mockProvider.Object);

ILoggerFactory factory = await manager.BuildAsync(_mockServiceProvider.Object, LogLevel.Information, _mockMonitor.Object);
_ = factory.CreateLogger("test");

mockProvider.Verify(p => p.CreateLogger(It.IsAny<string>()), Times.Never);
}

[TestMethod]
public async Task BuildAsync_InitializableExtensionProvider_WhenEnabled_CallsInitializeAsync()
Comment thread
Evangelink marked this conversation as resolved.
Outdated
{
LoggingManager manager = new();
Mock<IInitializableExtensionLoggerProvider> mockProvider = new();
mockProvider.Setup(p => p.IsEnabledAsync()).ReturnsAsync(true);
mockProvider.Setup(p => p.InitializeAsync()).Returns(Task.CompletedTask);
mockProvider.Setup(p => p.CreateLogger(It.IsAny<string>())).Returns(new Mock<ILogger>().Object);
Comment thread
Evangelink marked this conversation as resolved.
Outdated
Comment thread
Evangelink marked this conversation as resolved.
Outdated
manager.AddProvider((_, _) => mockProvider.Object);

ILoggerFactory factory = await manager.BuildAsync(_mockServiceProvider.Object, LogLevel.Information, _mockMonitor.Object);
_ = factory.CreateLogger("test");

mockProvider.Verify(p => p.InitializeAsync(), Times.Once);
mockProvider.Verify(p => p.CreateLogger("test"), Times.Once);
}

[TestMethod]
public async Task BuildAsync_InitializableExtensionProvider_WhenDisabled_DoesNotCallInitializeAsync()
{
LoggingManager manager = new();
Mock<IInitializableExtensionLoggerProvider> mockProvider = new();
mockProvider.Setup(p => p.IsEnabledAsync()).ReturnsAsync(false);
manager.AddProvider((_, _) => mockProvider.Object);

await manager.BuildAsync(_mockServiceProvider.Object, LogLevel.Information, _mockMonitor.Object);

mockProvider.Verify(p => p.InitializeAsync(), Times.Never);
}

[TestMethod]
public async Task BuildAsync_NonExtensionInitializableProvider_CallsInitializeAsync()
{
LoggingManager manager = new();
Mock<IInitializableLoggerProvider> mockProvider = new();
mockProvider.Setup(p => p.InitializeAsync()).Returns(Task.CompletedTask);
mockProvider.Setup(p => p.CreateLogger(It.IsAny<string>())).Returns(new Mock<ILogger>().Object);
manager.AddProvider((_, _) => mockProvider.Object);

ILoggerFactory factory = await manager.BuildAsync(_mockServiceProvider.Object, LogLevel.Information, _mockMonitor.Object);
_ = factory.CreateLogger("test");

mockProvider.Verify(p => p.InitializeAsync(), Times.Once);
Comment thread
Evangelink marked this conversation as resolved.
mockProvider.Verify(p => p.CreateLogger("test"), Times.Once);
}

[TestMethod]
public async Task BuildAsync_MultipleProviders_OnlyIncludesEnabledOnes()
{
LoggingManager manager = new();

Mock<IExtensionLoggerProvider> disabledProvider = new();
disabledProvider.Setup(p => p.IsEnabledAsync()).ReturnsAsync(false);

Mock<ILoggerProvider> enabledProvider = new();
enabledProvider.Setup(p => p.CreateLogger(It.IsAny<string>())).Returns(new Mock<ILogger>().Object);

manager.AddProvider((_, _) => disabledProvider.Object);
manager.AddProvider((_, _) => enabledProvider.Object);

ILoggerFactory factory = await manager.BuildAsync(_mockServiceProvider.Object, LogLevel.Information, _mockMonitor.Object);
_ = factory.CreateLogger("test");

disabledProvider.Verify(p => p.CreateLogger(It.IsAny<string>()), Times.Never);
enabledProvider.Verify(p => p.CreateLogger("test"), Times.Once);
Comment thread
Evangelink marked this conversation as resolved.
Outdated
}
}

internal interface IExtensionLoggerProvider : ILoggerProvider, IExtension;

internal interface IInitializableLoggerProvider : ILoggerProvider, IAsyncInitializableExtension;

internal interface IInitializableExtensionLoggerProvider : ILoggerProvider, IExtension, IAsyncInitializableExtension;
Loading