From f7839adc386baa581c75509e29820f45ab482c2b Mon Sep 17 00:00:00 2001 From: ta264 Date: Tue, 25 Feb 2020 21:53:40 +0000 Subject: [PATCH] Cache database for Unit tests to avoid repeated migrations (cherry picked from commit f3308827d0ede7895b0b8b3b251a17cda3a54120) --- src/NzbDrone.Core.Test/Framework/DbTest.cs | 47 ++++++++++++++++++- .../Framework/DbTestCleanup.cs | 26 ++++++++++ 2 files changed, 71 insertions(+), 2 deletions(-) create mode 100644 src/NzbDrone.Core.Test/Framework/DbTestCleanup.cs diff --git a/src/NzbDrone.Core.Test/Framework/DbTest.cs b/src/NzbDrone.Core.Test/Framework/DbTest.cs index afb6dbdb6..e38336375 100644 --- a/src/NzbDrone.Core.Test/Framework/DbTest.cs +++ b/src/NzbDrone.Core.Test/Framework/DbTest.cs @@ -1,10 +1,12 @@ using System; using System.Collections.Generic; using System.Data.SQLite; +using System.IO; using System.Linq; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; using NUnit.Framework; +using NzbDrone.Common.Extensions; using NzbDrone.Core.Datastore; using NzbDrone.Core.Datastore.Migration.Framework; @@ -65,8 +67,7 @@ namespace NzbDrone.Core.Test.Framework protected virtual ITestDatabase WithTestDb(MigrationContext migrationContext) { - var factory = Mocker.Resolve(); - var database = factory.Create(migrationContext); + var database = CreateDatabase(migrationContext); Mocker.SetConstant(database); switch (MigrationType) @@ -98,6 +99,48 @@ namespace NzbDrone.Core.Test.Framework return testDb; } + private IDatabase CreateDatabase(MigrationContext migrationContext) + { + var factory = Mocker.Resolve(); + + // If a special migration test or log migration then create new + if (migrationContext.BeforeMigration != null) + { + return factory.Create(migrationContext); + } + + // Otherwise try to use a cached migrated db + var cachedDb = GetCachedDatabase(migrationContext.MigrationType); + var testDb = GetTestDb(migrationContext.MigrationType); + if (File.Exists(cachedDb)) + { + TestLogger.Info($"Using cached initial database {cachedDb}"); + File.Copy(cachedDb, testDb); + return factory.Create(migrationContext); + } + else + { + var db = factory.Create(migrationContext); + GC.Collect(); + GC.WaitForPendingFinalizers(); + SQLiteConnection.ClearAllPools(); + + TestLogger.Info("Caching database"); + File.Copy(testDb, cachedDb); + return db; + } + } + + private string GetCachedDatabase(MigrationType type) + { + return Path.Combine(TestContext.CurrentContext.TestDirectory, $"cached_{type}.db"); + } + + private string GetTestDb(MigrationType type) + { + return type == MigrationType.Main ? TestFolderInfo.GetDatabase() : TestFolderInfo.GetLogDatabase(); + } + protected virtual void SetupLogging() { Mocker.SetConstant(NullLoggerProvider.Instance); diff --git a/src/NzbDrone.Core.Test/Framework/DbTestCleanup.cs b/src/NzbDrone.Core.Test/Framework/DbTestCleanup.cs new file mode 100644 index 000000000..587043e95 --- /dev/null +++ b/src/NzbDrone.Core.Test/Framework/DbTestCleanup.cs @@ -0,0 +1,26 @@ +using System.IO; +using NUnit.Framework; + +namespace NzbDrone.Core.Test +{ + [SetUpFixture] + public class RemoveCachedDatabase + { + [OneTimeSetUp] + [OneTimeTearDown] + public void ClearCachedDatabase() + { + var mainCache = Path.Combine(TestContext.CurrentContext.TestDirectory, $"cached_Main.db"); + if (File.Exists(mainCache)) + { + File.Delete(mainCache); + } + + var logCache = Path.Combine(TestContext.CurrentContext.TestDirectory, $"cached_Log.db"); + if (File.Exists(logCache)) + { + File.Delete(logCache); + } + } + } +}