diff --git a/test/Common.FunctionalTests/Inprocess/FixtureLoggedTest.cs b/test/Common.FunctionalTests/Inprocess/FixtureLoggedTest.cs new file mode 100644 index 0000000000..4604687991 --- /dev/null +++ b/test/Common.FunctionalTests/Inprocess/FixtureLoggedTest.cs @@ -0,0 +1,31 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Reflection; +using Microsoft.Extensions.Logging.Testing; +using Xunit.Abstractions; + +namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests +{ + public class FixtureLoggedTest: LoggedTest + { + private readonly IISTestSiteFixture _fixture; + + public FixtureLoggedTest(IISTestSiteFixture fixture) + { + _fixture = fixture; + } + + public override void Initialize(MethodInfo methodInfo, object[] testMethodArguments, ITestOutputHelper testOutputHelper) + { + base.Initialize(methodInfo, testMethodArguments, testOutputHelper); + _fixture.Attach(this); + } + + public override void Dispose() + { + _fixture.Detach(this); + base.Dispose(); + } + } +} diff --git a/test/Common.FunctionalTests/Inprocess/SynchronousReadAndWriteTests.cs b/test/Common.FunctionalTests/Inprocess/SynchronousReadAndWriteTests.cs index 9b57d4996b..03aa0e16e6 100644 --- a/test/Common.FunctionalTests/Inprocess/SynchronousReadAndWriteTests.cs +++ b/test/Common.FunctionalTests/Inprocess/SynchronousReadAndWriteTests.cs @@ -6,23 +6,22 @@ using System.Collections.Generic; using System.Linq; using System.Net.Http; using System.Threading.Tasks; -using Microsoft.AspNetCore.Server.IntegrationTesting; using Microsoft.AspNetCore.Testing.xunit; using Xunit; namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests { [Collection(IISTestSiteCollection.Name)] - public class SynchronousReadAndWriteTests + public class SynchronousReadAndWriteTests: FixtureLoggedTest { private readonly IISTestSiteFixture _fixture; - public SynchronousReadAndWriteTests(IISTestSiteFixture fixture) + public SynchronousReadAndWriteTests(IISTestSiteFixture fixture): base(fixture) { _fixture = fixture; } - [ConditionalFact(Skip = "See: https://github.com/aspnet/IISIntegration/issues/766")] + [ConditionalFact] public async Task ReadAndWriteSynchronously() { for (int i = 0; i < 100; i++) diff --git a/test/Common.FunctionalTests/Utilities/IISTestSiteFixture.cs b/test/Common.FunctionalTests/Utilities/IISTestSiteFixture.cs index d19dad36d0..1a60e85246 100644 --- a/test/Common.FunctionalTests/Utilities/IISTestSiteFixture.cs +++ b/test/Common.FunctionalTests/Utilities/IISTestSiteFixture.cs @@ -2,10 +2,12 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; +using System.Collections.Generic; using System.IO; using System.Net.Http; using System.Threading; using Microsoft.AspNetCore.Server.IntegrationTesting; +using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Logging.Testing; @@ -14,6 +16,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests public class IISTestSiteFixture : IDisposable { private readonly ApplicationDeployer _deployer; + private readonly ForwardingProvider _forwardingProvider; public IISTestSiteFixture() { @@ -30,14 +33,17 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests PublishApplicationBeforeDeployment = true, }; + _forwardingProvider = new ForwardingProvider(); + var loggerFactory = logging.CreateLoggerFactory(null, nameof(IISTestSiteFixture)); + loggerFactory.AddProvider(_forwardingProvider); if (deploymentParameters.ServerType == ServerType.IIS) { // Currently hosting throws if the Servertype = IIS. - _deployer = new IISDeployer(deploymentParameters, logging.CreateLoggerFactory(null, nameof(IISTestSiteFixture))); + _deployer = new IISDeployer(deploymentParameters, loggerFactory); } else if (deploymentParameters.ServerType == ServerType.IISExpress) { - _deployer = new IISExpressDeployer(deploymentParameters, logging.CreateLoggerFactory(null, nameof(IISTestSiteFixture))); + _deployer = new IISExpressDeployer(deploymentParameters, loggerFactory); } DeploymentResult = _deployer.DeployAsync().Result; @@ -60,5 +66,88 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests { _deployer.Dispose(); } + + public void Attach(LoggedTest test) + { + if (_forwardingProvider.LoggerFactory != null) + { + throw new InvalidOperationException("Test instance is already attached to this fixture"); + } + + _forwardingProvider.LoggerFactory = test.LoggerFactory; + } + + public void Detach(LoggedTest test) + { + if (_forwardingProvider.LoggerFactory != test.LoggerFactory) + { + throw new InvalidOperationException("Different test is attached to this fixture"); + } + + _forwardingProvider.LoggerFactory = null; + } + + private class ForwardingProvider : ILoggerProvider + { + private readonly List _loggers = new List(); + + private ILoggerFactory _loggerFactory; + + public ILoggerFactory LoggerFactory + { + get => _loggerFactory; + set + { + + lock (_loggers) + { + _loggerFactory = value; + foreach (var logger in _loggers) + { + logger.Logger = _loggerFactory?.CreateLogger("FIXTURE:" + logger.Name); + } + } + } + } + + public void Dispose() + { + lock (_loggers) + { + _loggers.Clear(); + } + } + + public ILogger CreateLogger(string categoryName) + { + lock (_loggers) + { + var logger = new ForwardingLogger(categoryName); + _loggers.Add(logger); + return logger; + } + } + } + + internal class ForwardingLogger : ILogger + { + public ForwardingLogger(string name) + { + Name = name; + } + + public ILogger Logger { get; set; } + public string Name { get; set; } + + public void Log(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func formatter) + { + Logger?.Log(logLevel, eventId, state, exception, formatter); + } + + public bool IsEnabled(LogLevel logLevel) => Logger?.IsEnabled(logLevel) == true; + + public IDisposable BeginScope(TState state) => Logger?.BeginScope(state); + } } + }