mirror of
https://github.com/ppy/osu.git
synced 2024-12-14 10:12:54 +08:00
Merge pull request #15040 from peppy/realm-test-game-host
Update realm tests to run inside a `GameHost` to allow running on update thread
This commit is contained in:
commit
7bb401b974
@ -4,7 +4,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Nito.AsyncEx;
|
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Logging;
|
using osu.Framework.Logging;
|
||||||
using osu.Framework.Platform;
|
using osu.Framework.Platform;
|
||||||
@ -28,42 +27,69 @@ namespace osu.Game.Tests.Database
|
|||||||
|
|
||||||
protected void RunTestWithRealm(Action<RealmContextFactory, Storage> testAction, [CallerMemberName] string caller = "")
|
protected void RunTestWithRealm(Action<RealmContextFactory, Storage> testAction, [CallerMemberName] string caller = "")
|
||||||
{
|
{
|
||||||
AsyncContext.Run(() =>
|
using (HeadlessGameHost host = new CleanRunHeadlessGameHost(caller))
|
||||||
{
|
{
|
||||||
var testStorage = storage.GetStorageForDirectory(caller);
|
host.Run(new RealmTestGame(() =>
|
||||||
|
|
||||||
using (var realmFactory = new RealmContextFactory(testStorage, caller))
|
|
||||||
{
|
{
|
||||||
Logger.Log($"Running test using realm file {testStorage.GetFullPath(realmFactory.Filename)}");
|
var testStorage = storage.GetStorageForDirectory(caller);
|
||||||
testAction(realmFactory, testStorage);
|
|
||||||
|
|
||||||
realmFactory.Dispose();
|
using (var realmFactory = new RealmContextFactory(testStorage, caller))
|
||||||
|
{
|
||||||
|
Logger.Log($"Running test using realm file {testStorage.GetFullPath(realmFactory.Filename)}");
|
||||||
|
testAction(realmFactory, testStorage);
|
||||||
|
|
||||||
Logger.Log($"Final database size: {getFileSize(testStorage, realmFactory)}");
|
realmFactory.Dispose();
|
||||||
realmFactory.Compact();
|
|
||||||
Logger.Log($"Final database size after compact: {getFileSize(testStorage, realmFactory)}");
|
Logger.Log($"Final database size: {getFileSize(testStorage, realmFactory)}");
|
||||||
}
|
realmFactory.Compact();
|
||||||
});
|
Logger.Log($"Final database size after compact: {getFileSize(testStorage, realmFactory)}");
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void RunTestWithRealmAsync(Func<RealmContextFactory, Storage, Task> testAction, [CallerMemberName] string caller = "")
|
protected void RunTestWithRealmAsync(Func<RealmContextFactory, Storage, Task> testAction, [CallerMemberName] string caller = "")
|
||||||
{
|
{
|
||||||
AsyncContext.Run(async () =>
|
using (HeadlessGameHost host = new CleanRunHeadlessGameHost(caller))
|
||||||
{
|
{
|
||||||
var testStorage = storage.GetStorageForDirectory(caller);
|
host.Run(new RealmTestGame(async () =>
|
||||||
|
|
||||||
using (var realmFactory = new RealmContextFactory(testStorage, caller))
|
|
||||||
{
|
{
|
||||||
Logger.Log($"Running test using realm file {testStorage.GetFullPath(realmFactory.Filename)}");
|
var testStorage = storage.GetStorageForDirectory(caller);
|
||||||
await testAction(realmFactory, testStorage);
|
|
||||||
|
|
||||||
realmFactory.Dispose();
|
using (var realmFactory = new RealmContextFactory(testStorage, caller))
|
||||||
|
{
|
||||||
|
Logger.Log($"Running test using realm file {testStorage.GetFullPath(realmFactory.Filename)}");
|
||||||
|
await testAction(realmFactory, testStorage);
|
||||||
|
|
||||||
Logger.Log($"Final database size: {getFileSize(testStorage, realmFactory)}");
|
realmFactory.Dispose();
|
||||||
realmFactory.Compact();
|
|
||||||
Logger.Log($"Final database size after compact: {getFileSize(testStorage, realmFactory)}");
|
Logger.Log($"Final database size: {getFileSize(testStorage, realmFactory)}");
|
||||||
}
|
realmFactory.Compact();
|
||||||
});
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class RealmTestGame : Framework.Game
|
||||||
|
{
|
||||||
|
public RealmTestGame(Func<Task> work)
|
||||||
|
{
|
||||||
|
// ReSharper disable once AsyncVoidLambda
|
||||||
|
Scheduler.Add(async () =>
|
||||||
|
{
|
||||||
|
await work().ConfigureAwait(true);
|
||||||
|
Exit();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public RealmTestGame(Action work)
|
||||||
|
{
|
||||||
|
Scheduler.Add(() =>
|
||||||
|
{
|
||||||
|
work();
|
||||||
|
Exit();
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static long getFileSize(Storage testStorage, RealmContextFactory realmFactory)
|
private static long getFileSize(Storage testStorage, RealmContextFactory realmFactory)
|
||||||
|
@ -135,9 +135,8 @@ namespace osu.Game.Database
|
|||||||
if (IsDisposed)
|
if (IsDisposed)
|
||||||
throw new ObjectDisposedException(nameof(RealmContextFactory));
|
throw new ObjectDisposedException(nameof(RealmContextFactory));
|
||||||
|
|
||||||
// TODO: this can be added for safety once we figure how to bypass in test
|
if (!ThreadSafety.IsUpdateThread)
|
||||||
// if (!ThreadSafety.IsUpdateThread)
|
throw new InvalidOperationException($"{nameof(BlockAllOperations)} must be called from the update thread.");
|
||||||
// throw new InvalidOperationException($"{nameof(BlockAllOperations)} must be called from the update thread.");
|
|
||||||
|
|
||||||
Logger.Log(@"Blocking realm operations.", LoggingTarget.Database);
|
Logger.Log(@"Blocking realm operations.", LoggingTarget.Database);
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@ using System.Collections.Generic;
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using System.Threading;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Audio;
|
using osu.Framework.Audio;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
@ -410,11 +411,28 @@ namespace osu.Game
|
|||||||
{
|
{
|
||||||
Logger.Log($@"Migrating osu! data from ""{Storage.GetFullPath(string.Empty)}"" to ""{path}""...");
|
Logger.Log($@"Migrating osu! data from ""{Storage.GetFullPath(string.Empty)}"" to ""{path}""...");
|
||||||
|
|
||||||
using (realmFactory.BlockAllOperations())
|
IDisposable realmBlocker = null;
|
||||||
|
|
||||||
|
try
|
||||||
{
|
{
|
||||||
contextFactory.FlushConnections();
|
ManualResetEventSlim readyToRun = new ManualResetEventSlim();
|
||||||
|
|
||||||
|
Scheduler.Add(() =>
|
||||||
|
{
|
||||||
|
realmBlocker = realmFactory.BlockAllOperations();
|
||||||
|
contextFactory.FlushConnections();
|
||||||
|
|
||||||
|
readyToRun.Set();
|
||||||
|
}, false);
|
||||||
|
|
||||||
|
readyToRun.Wait();
|
||||||
|
|
||||||
(Storage as OsuStorage)?.Migrate(Host.GetStorage(path));
|
(Storage as OsuStorage)?.Migrate(Host.GetStorage(path));
|
||||||
}
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
realmBlocker?.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
Logger.Log(@"Migration complete!");
|
Logger.Log(@"Migration complete!");
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user