From a4f83ca46143502067d4f69ec2b6c657c5eb5478 Mon Sep 17 00:00:00 2001 From: David Driscoll Date: Sat, 3 Feb 2024 12:17:08 -0500 Subject: [PATCH] Fixed a bug in the launchpad web fixture that was trying to dispose of the host even if it had not yet been set properly. (#1792) --- .build/Build.cs | 7 + .../LaunchPadWebAppFixture.cs | 173 ++++++++---------- 2 files changed, 88 insertions(+), 92 deletions(-) diff --git a/.build/Build.cs b/.build/Build.cs index a4acade8c..30b0a34f7 100644 --- a/.build/Build.cs +++ b/.build/Build.cs @@ -67,6 +67,13 @@ public static int Main() public Target Restore => _ => _.Inherit(x => x.CoreRestore); public Target Test => _ => _.Inherit(x => x.CoreTest); + /// + /// Only run the JetBrains cleanup code when running on the server + /// + public Target JetBrainsCleanupCode => _ => _ + .Inherit(x => x.JetBrainsCleanupCode) + .OnlyWhenStatic(() => IsServerBuild); + [Solution(GenerateProjects = true)] private Solution Solution { get; } = null!; Nuke.Common.ProjectModel.Solution IHaveSolution.Solution => Solution; diff --git a/src/AspNetCore.Testing/LaunchPadWebAppFixture.cs b/src/AspNetCore.Testing/LaunchPadWebAppFixture.cs index b32085446..6d55c2b91 100644 --- a/src/AspNetCore.Testing/LaunchPadWebAppFixture.cs +++ b/src/AspNetCore.Testing/LaunchPadWebAppFixture.cs @@ -1,11 +1,10 @@ using Alba; using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Logging.Abstractions; namespace Rocket.Surgery.LaunchPad.AspNetCore.Testing; /// -/// A fixture used to bootstrap the alba test server with a custom sql extension +/// A fixture used to bootstrap the alba test server with a custom sql extension /// public abstract class LaunchPadWebAppFixture : ILaunchPadWebAppFixture where TEntryPoint : class @@ -16,105 +15,111 @@ public abstract class LaunchPadWebAppFixture : ILaunchPadWebAppFixt private IAlbaHost? _host; /// - /// The base constructor for use with hte web app fixture + /// The base constructor for use with hte web app fixture /// /// /// - protected LaunchPadWebAppFixture(IResettableAlbaExtension? resettableAlbaExtension, params IAlbaExtension[] extensions) + protected LaunchPadWebAppFixture(IResettableAlbaExtension resettableAlbaExtension, params IAlbaExtension[] extensions) : this( + [resettableAlbaExtension, ..extensions,] + ) { - _loggerFactory = new AppFixtureLoggerFactory(); _sqlExtension = resettableAlbaExtension; - _extensions = new IAlbaExtension[] - { - new LaunchPadExtension(this, _loggerFactory), - // ReSharper disable once NullableWarningSuppressionIsUsed - _sqlExtension! - } - // ReSharper disable once NullableWarningSuppressionIsUsed - .Where(z => z != null!) - .Concat(extensions) - .ToArray(); } - // ReSharper disable once NullableWarningSuppressionIsUsed /// - /// The underlying alba host + /// The base constructor for use with hte web app fixture /// - public IAlbaHost AlbaHost => _host!; + /// + protected LaunchPadWebAppFixture(params IAlbaExtension[] extensions) + { + _loggerFactory = new(); + _extensions = [new LaunchPadExtension(this, _loggerFactory), ..extensions,]; + } /// - /// Set the loggerfactory when initializing the test + /// Method used to start the alba host /// - /// - public void SetLoggerFactory(ILoggerFactory loggerFactory) + public async Task InitializeAsync() { - _loggerFactory.SetLoggerFactory(loggerFactory); + _host = await Alba.AlbaHost.For(_extensions); } /// - /// Method to reset the database if provided + /// Method used to dispose the alba host /// - public void Reset() + public async Task DisposeAsync() { - if (_sqlExtension is null || _host is null) return; - _sqlExtension.Reset(AlbaHost.Services); + if (_host is { }) await _host.DisposeAsync(); + _loggerFactory.Dispose(); + if (_sqlExtension != null) await _sqlExtension.DisposeAsync(); } /// - /// Method to reset the database if provided + /// The dispose method /// - public async Task ResetAsync() + /// + protected virtual void Dispose(bool disposing) { - if (_sqlExtension is null || _host is null) return; + if (!disposing) return; + _loggerFactory.Dispose(); + _sqlExtension?.Dispose(); + _host?.Dispose(); + } - await _sqlExtension.ResetAsync(AlbaHost.Services); + // ReSharper disable once NullableWarningSuppressionIsUsed + /// + /// The underlying alba host + /// + public IAlbaHost AlbaHost => _host!; + + /// + /// Set the logger factory when initializing the test + /// + /// + public void SetLoggerFactory(ILoggerFactory loggerFactory) + { + _loggerFactory.SetLoggerFactory(loggerFactory); } /// - /// Method used to start the alba host + /// Method to reset the database if provided /// - public async Task InitializeAsync() + public void Reset() { - _host = await Alba.AlbaHost.For(_extensions); + if (_sqlExtension is null || _host is null) return; + _sqlExtension.Reset(AlbaHost.Services); } /// - /// Method used to dispose the alba host + /// Method to reset the database if provided /// - public async Task DisposeAsync() + public Task ResetAsync() { - await AlbaHost.DisposeAsync(); - _loggerFactory.Dispose(); + if (_sqlExtension is null || _host is null) return Task.CompletedTask; - if (_sqlExtension != null) - { - await _sqlExtension.DisposeAsync(); - } + return _sqlExtension.ResetAsync(AlbaHost.Services); } -#pragma warning disable CA1816 + #pragma warning disable CA1816 async ValueTask IAsyncDisposable.DisposeAsync() -#pragma warning restore CA1816 + #pragma warning restore CA1816 { await DisposeAsync().ConfigureAwait(false); } /// - /// The dispose method + /// The dispose method /// - /// - protected virtual void Dispose(bool disposing) + public void Dispose() { - if (!disposing) return; - _loggerFactory.Dispose(); - _sqlExtension?.Dispose(); - AlbaHost.Dispose(); + Dispose(true); + GC.SuppressFinalize(this); } - class AppFixtureLoggerFactory : ILoggerFactory + private class AppFixtureLoggerFactory : ILoggerFactory { + private readonly List _deferredLoggers = new(); private ILoggerFactory? _innerLoggerFactory; - private List _deferredLoggers = new(); public void SetLoggerFactory(ILoggerFactory loggerFactory) { @@ -125,11 +130,15 @@ public void SetLoggerFactory(ILoggerFactory loggerFactory) } } - public void Dispose() + private DeferredLogger AddDeferredLogger(string categoryName) { - _innerLoggerFactory?.Dispose(); + var logger = new DeferredLogger(categoryName); + _deferredLoggers.Add(logger); + return logger; } + public void Dispose() { } + public void AddProvider(ILoggerProvider provider) { _innerLoggerFactory?.AddProvider(provider); @@ -139,33 +148,36 @@ public ILogger CreateLogger(string categoryName) { return _innerLoggerFactory?.CreateLogger(categoryName) ?? AddDeferredLogger(categoryName); } - - private DeferredLogger AddDeferredLogger(string categoryName) - { - var logger = new DeferredLogger(categoryName); - _deferredLoggers.Add(logger); - return logger; - } } - class DeferredLogger : ILogger + private class DeferredLogger(string categoryName) : ILogger { - public string CategoryName { get; } - private List<(LogLevel logLevel, EventId eventId, string text)> _deferredLogs = new(); + private readonly List<(LogLevel logLevel, EventId eventId, string text)> _deferredLogs = []; private ILogger? _logger; + public string CategoryName { get; } = categoryName; - public DeferredLogger(string categoryName) + public void SetLogger(ILogger logger) { - CategoryName = categoryName; + _logger = logger; + foreach (var log in _deferredLogs) + { + #pragma warning disable CA1848 + #pragma warning disable CA2254 + // ReSharper disable once TemplateIsNotCompileTimeConstantProblem + _logger.Log(log.logLevel, log.eventId, log.text); + #pragma warning restore CA2254 + #pragma warning restore CA1848 + } } - + public void Log(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func formatter) { if (_logger is null) { - _deferredLogs.Add((logLevel, eventId, formatter(state, exception))); + _deferredLogs.Add(( logLevel, eventId, formatter(state, exception) )); return; } + _logger.Log(logLevel, eventId, state, exception, formatter); } @@ -178,28 +190,5 @@ public bool IsEnabled(LogLevel logLevel) { return _logger?.BeginScope(state); } - - public void SetLogger(ILogger logger) - { - _logger = logger; - foreach (var log in _deferredLogs) - { -#pragma warning disable CA1848 -#pragma warning disable CA2254 - // ReSharper disable once TemplateIsNotCompileTimeConstantProblem - _logger.Log(log.logLevel, log.eventId, log.text); -#pragma warning restore CA2254 -#pragma warning restore CA1848 - } - } - } - - /// - /// The dispose method - /// - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); } -} +} \ No newline at end of file