From 312ab962779e75fd4ea6f00c3359cf35105eafff Mon Sep 17 00:00:00 2001 From: Paul Johnson Date: Fri, 11 Dec 2020 18:20:07 +0000 Subject: [PATCH] Resolve issues with AdvancedMigrationTests --- .../Persistence/UmbracoDatabaseFactory.cs | 11 ----- .../UmbracoTestServerTestBase.cs | 3 +- .../Testing/SqlDeveloperTestDatabase.cs | 3 +- .../Testing/TestDatabaseFactory.cs | 6 +-- .../TestUmbracoDatabaseFactoryProvider.cs | 48 +++++++++++++++++++ .../Testing/UmbracoIntegrationTest.cs | 22 ++++----- 6 files changed, 64 insertions(+), 29 deletions(-) create mode 100644 src/Umbraco.Tests.Integration/Testing/TestUmbracoDatabaseFactoryProvider.cs diff --git a/src/Umbraco.Infrastructure/Persistence/UmbracoDatabaseFactory.cs b/src/Umbraco.Infrastructure/Persistence/UmbracoDatabaseFactory.cs index 7b98bd150e..5c3c984677 100644 --- a/src/Umbraco.Infrastructure/Persistence/UmbracoDatabaseFactory.cs +++ b/src/Umbraco.Infrastructure/Persistence/UmbracoDatabaseFactory.cs @@ -327,16 +327,5 @@ namespace Umbraco.Core.Persistence //db?.Dispose(); Volatile.Write(ref _initialized, false); } - - // during tests, the thread static var can leak between tests - // this method provides a way to force-reset the variable - internal void ResetForTests() - { - // TODO: remove all this eventually - //var db = _umbracoDatabaseAccessor.UmbracoDatabase; - //_umbracoDatabaseAccessor.UmbracoDatabase = null; - //db?.Dispose(); - //_databaseScopeAccessor.Scope = null; - } } } diff --git a/src/Umbraco.Tests.Integration/TestServerTest/UmbracoTestServerTestBase.cs b/src/Umbraco.Tests.Integration/TestServerTest/UmbracoTestServerTestBase.cs index d60f49971a..93769eaaed 100644 --- a/src/Umbraco.Tests.Integration/TestServerTest/UmbracoTestServerTestBase.cs +++ b/src/Umbraco.Tests.Integration/TestServerTest/UmbracoTestServerTestBase.cs @@ -132,11 +132,12 @@ namespace Umbraco.Tests.Integration.TestServerTest public override void ConfigureServices(IServiceCollection services) { + services.AddTransient(); var typeLoader = services.AddTypeLoader(GetType().Assembly, TestHelper.GetWebHostEnvironment(), TestHelper.GetHostingEnvironment(), TestHelper.ConsoleLoggerFactory, AppCaches.NoCache, Configuration, TestHelper.Profiler); var builder = new UmbracoBuilder(services, Configuration, typeLoader); - + builder .AddConfiguration() .AddTestCore(TestHelper) // This is the important one! diff --git a/src/Umbraco.Tests.Integration/Testing/SqlDeveloperTestDatabase.cs b/src/Umbraco.Tests.Integration/Testing/SqlDeveloperTestDatabase.cs index 560bcbe00a..52be6d5472 100644 --- a/src/Umbraco.Tests.Integration/Testing/SqlDeveloperTestDatabase.cs +++ b/src/Umbraco.Tests.Integration/Testing/SqlDeveloperTestDatabase.cs @@ -31,7 +31,7 @@ namespace Umbraco.Tests.Integration.Testing private readonly IUmbracoDatabaseFactory _databaseFactory; private readonly IDictionary _testDatabases; private UmbracoDatabase.CommandInfo[] _cachedDatabaseInitCommands; - + private BlockingCollection _prepareQueue; private BlockingCollection _readySchemaQueue; private BlockingCollection _readyEmptyQueue; @@ -54,7 +54,6 @@ namespace Umbraco.Tests.Integration.Testing new TestDbMeta(2, false, masterConnectionString), new TestDbMeta(3, true, masterConnectionString), - new TestDbMeta(4, true, masterConnectionString), }.ToDictionary(x => x.Id); Instance = this; // For GlobalSetupTeardown.cs diff --git a/src/Umbraco.Tests.Integration/Testing/TestDatabaseFactory.cs b/src/Umbraco.Tests.Integration/Testing/TestDatabaseFactory.cs index 0f403818b7..3ed2b6b49a 100644 --- a/src/Umbraco.Tests.Integration/Testing/TestDatabaseFactory.cs +++ b/src/Umbraco.Tests.Integration/Testing/TestDatabaseFactory.cs @@ -7,11 +7,11 @@ namespace Umbraco.Tests.Integration.Testing { public class TestDatabaseFactory { - public static ITestDatabase Create(string filesPath, ILoggerFactory loggerFactory, IUmbracoDatabaseFactory dbFactory) + public static ITestDatabase Create(string filesPath, ILoggerFactory loggerFactory, TestUmbracoDatabaseFactoryProvider dbFactory) { return RuntimeInformation.IsOSPlatform(OSPlatform.Windows) - ? CreateLocalDb(filesPath, loggerFactory, dbFactory) - : CreateSqlDeveloper(loggerFactory, dbFactory); + ? CreateLocalDb(filesPath, loggerFactory, dbFactory.Create()) + : CreateSqlDeveloper(loggerFactory, dbFactory.Create()); } private static ITestDatabase CreateLocalDb(string filesPath, ILoggerFactory loggerFactory, IUmbracoDatabaseFactory dbFactory) diff --git a/src/Umbraco.Tests.Integration/Testing/TestUmbracoDatabaseFactoryProvider.cs b/src/Umbraco.Tests.Integration/Testing/TestUmbracoDatabaseFactoryProvider.cs new file mode 100644 index 0000000000..3eb3757207 --- /dev/null +++ b/src/Umbraco.Tests.Integration/Testing/TestUmbracoDatabaseFactoryProvider.cs @@ -0,0 +1,48 @@ +using System; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; +using Umbraco.Core.Configuration.Models; +using Umbraco.Core.Persistence; +using Umbraco.Core.Persistence.Mappers; + +namespace Umbraco.Tests.Integration.Testing +{ + /// + /// I want to be able to create a database for integration testsing without setting the connection string on the + /// singleton database factory forever. + /// + public class TestUmbracoDatabaseFactoryProvider + { + private readonly ILoggerFactory _loggerFactory; + private readonly IOptions _globalSettings; + private readonly IOptions _connectionStrings; + private readonly Lazy _mappers; + private readonly IDbProviderFactoryCreator _dbProviderFactoryCreator; + + public TestUmbracoDatabaseFactoryProvider( + ILoggerFactory loggerFactory, + IOptions globalSettings, + IOptions connectionStrings, + Lazy mappers, + IDbProviderFactoryCreator dbProviderFactoryCreator) + { + _loggerFactory = loggerFactory; + _globalSettings = globalSettings; + _connectionStrings = connectionStrings; + _mappers = mappers; + _dbProviderFactoryCreator = dbProviderFactoryCreator; + } + + public IUmbracoDatabaseFactory Create() + { + // ReSharper disable once ArrangeMethodOrOperatorBody + return new UmbracoDatabaseFactory( + _loggerFactory.CreateLogger(), + _loggerFactory, + _globalSettings.Value, + _connectionStrings.Value, + _mappers, + _dbProviderFactoryCreator); + } + } +} diff --git a/src/Umbraco.Tests.Integration/Testing/UmbracoIntegrationTest.cs b/src/Umbraco.Tests.Integration/Testing/UmbracoIntegrationTest.cs index a376aff38d..3da4ec94d6 100644 --- a/src/Umbraco.Tests.Integration/Testing/UmbracoIntegrationTest.cs +++ b/src/Umbraco.Tests.Integration/Testing/UmbracoIntegrationTest.cs @@ -165,6 +165,7 @@ namespace Umbraco.Tests.Integration.Testing public virtual void ConfigureServices(IServiceCollection services) { services.AddSingleton(TestHelper.DbProviderFactoryCreator); + services.AddTransient(); var webHostEnvironment = TestHelper.GetWebHostEnvironment(); services.AddRequiredNetCoreServices(TestHelper, webHostEnvironment); @@ -247,10 +248,11 @@ namespace Umbraco.Tests.Integration.Testing protected void UseTestLocalDb(IServiceProvider serviceProvider) { var state = serviceProvider.GetRequiredService(); + var testDatabaseFactoryProvider = serviceProvider.GetRequiredService(); var databaseFactory = serviceProvider.GetRequiredService(); // This will create a db, install the schema and ensure the app is configured to run - InstallTestLocalDb(databaseFactory, serviceProvider.GetRequiredService(), state, TestHelper.WorkingDirectory); + InstallTestLocalDb(testDatabaseFactoryProvider, databaseFactory, serviceProvider.GetRequiredService(), state, TestHelper.WorkingDirectory); TestDBConnectionString = databaseFactory.ConnectionString; InMemoryConfiguration["ConnectionStrings:" + Constants.System.UmbracoConnectionName] = TestDBConnectionString; } @@ -267,7 +269,7 @@ namespace Umbraco.Tests.Integration.Testing /// /// There must only be ONE instance shared between all tests in a session /// - private static ITestDatabase GetOrCreateDatabase(string filesPath, ILoggerFactory loggerFactory, IUmbracoDatabaseFactory dbFactory) + private static ITestDatabase GetOrCreateDatabase(string filesPath, ILoggerFactory loggerFactory, TestUmbracoDatabaseFactoryProvider dbFactory) { lock (_dbLocker) { @@ -282,16 +284,12 @@ namespace Umbraco.Tests.Integration.Testing /// /// Creates a LocalDb instance to use for the test /// - /// - /// - /// - /// - /// - /// - /// private void InstallTestLocalDb( - IUmbracoDatabaseFactory databaseFactory, ILoggerFactory loggerFactory, - IRuntimeState runtimeState, string workingDirectory) + TestUmbracoDatabaseFactoryProvider testUmbracoDatabaseFactoryProvider, + IUmbracoDatabaseFactory databaseFactory, + ILoggerFactory loggerFactory, + IRuntimeState runtimeState, + string workingDirectory) { var dbFilePath = Path.Combine(workingDirectory, "LocalDb"); @@ -307,7 +305,7 @@ namespace Umbraco.Tests.Integration.Testing if (!Directory.Exists(dbFilePath)) Directory.CreateDirectory(dbFilePath); - var db = GetOrCreateDatabase(dbFilePath, loggerFactory, databaseFactory); + var db = GetOrCreateDatabase(dbFilePath, loggerFactory, testUmbracoDatabaseFactoryProvider); switch (testOptions.Database) {