Merge remote-tracking branch 'upstream/master' into fix-new-samples-starting-while-gameplay-paused

This commit is contained in:
Salman Ahmed
2020-09-19 05:53:04 +03:00
32 changed files with 476 additions and 240 deletions

View File

@ -28,17 +28,17 @@ using FileInfo = System.IO.FileInfo;
namespace osu.Game.Tests.Beatmaps.IO
{
[TestFixture]
public class ImportBeatmapTest
public class ImportBeatmapTest : ImportTest
{
[Test]
public async Task TestImportWhenClosed()
{
// unfortunately for the time being we need to reference osu.Framework.Desktop for a game host here.
using (HeadlessGameHost host = new CleanRunHeadlessGameHost())
using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(ImportBeatmapTest)))
{
try
{
await LoadOszIntoOsu(loadOsu(host));
await LoadOszIntoOsu(LoadOsuIntoHost(host));
}
finally
{
@ -51,11 +51,11 @@ namespace osu.Game.Tests.Beatmaps.IO
public async Task TestImportThenDelete()
{
// unfortunately for the time being we need to reference osu.Framework.Desktop for a game host here.
using (HeadlessGameHost host = new CleanRunHeadlessGameHost())
using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(ImportBeatmapTest)))
{
try
{
var osu = loadOsu(host);
var osu = LoadOsuIntoHost(host);
var imported = await LoadOszIntoOsu(osu);
@ -72,11 +72,11 @@ namespace osu.Game.Tests.Beatmaps.IO
public async Task TestImportThenImport()
{
// unfortunately for the time being we need to reference osu.Framework.Desktop for a game host here.
using (HeadlessGameHost host = new CleanRunHeadlessGameHost())
using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(ImportBeatmapTest)))
{
try
{
var osu = loadOsu(host);
var osu = LoadOsuIntoHost(host);
var imported = await LoadOszIntoOsu(osu);
var importedSecondTime = await LoadOszIntoOsu(osu);
@ -98,11 +98,11 @@ namespace osu.Game.Tests.Beatmaps.IO
[Test]
public async Task TestImportThenImportWithReZip()
{
using (HeadlessGameHost host = new CleanRunHeadlessGameHost())
using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(ImportBeatmapTest)))
{
try
{
var osu = loadOsu(host);
var osu = LoadOsuIntoHost(host);
var temp = TestResources.GetTestBeatmapForImport();
@ -156,11 +156,11 @@ namespace osu.Game.Tests.Beatmaps.IO
[Test]
public async Task TestImportThenImportWithChangedFile()
{
using (HeadlessGameHost host = new CleanRunHeadlessGameHost())
using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(ImportBeatmapTest)))
{
try
{
var osu = loadOsu(host);
var osu = LoadOsuIntoHost(host);
var temp = TestResources.GetTestBeatmapForImport();
@ -207,11 +207,11 @@ namespace osu.Game.Tests.Beatmaps.IO
[Test]
public async Task TestImportThenImportWithDifferentFilename()
{
using (HeadlessGameHost host = new CleanRunHeadlessGameHost())
using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(ImportBeatmapTest)))
{
try
{
var osu = loadOsu(host);
var osu = LoadOsuIntoHost(host);
var temp = TestResources.GetTestBeatmapForImport();
@ -259,11 +259,11 @@ namespace osu.Game.Tests.Beatmaps.IO
public async Task TestImportCorruptThenImport()
{
// unfortunately for the time being we need to reference osu.Framework.Desktop for a game host here.
using (HeadlessGameHost host = new CleanRunHeadlessGameHost())
using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(ImportBeatmapTest)))
{
try
{
var osu = loadOsu(host);
var osu = LoadOsuIntoHost(host);
var imported = await LoadOszIntoOsu(osu);
@ -301,7 +301,7 @@ namespace osu.Game.Tests.Beatmaps.IO
public async Task TestRollbackOnFailure()
{
// unfortunately for the time being we need to reference osu.Framework.Desktop for a game host here.
using (HeadlessGameHost host = new CleanRunHeadlessGameHost())
using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(ImportBeatmapTest)))
{
try
{
@ -314,7 +314,7 @@ namespace osu.Game.Tests.Beatmaps.IO
Interlocked.Increment(ref loggedExceptionCount);
};
var osu = loadOsu(host);
var osu = LoadOsuIntoHost(host);
var manager = osu.Dependencies.Get<BeatmapManager>();
// ReSharper disable once AccessToModifiedClosure
@ -378,11 +378,11 @@ namespace osu.Game.Tests.Beatmaps.IO
public async Task TestImportThenDeleteThenImport()
{
// unfortunately for the time being we need to reference osu.Framework.Desktop for a game host here.
using (HeadlessGameHost host = new CleanRunHeadlessGameHost())
using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(ImportBeatmapTest)))
{
try
{
var osu = loadOsu(host);
var osu = LoadOsuIntoHost(host);
var imported = await LoadOszIntoOsu(osu);
@ -406,11 +406,11 @@ namespace osu.Game.Tests.Beatmaps.IO
public async Task TestImportThenDeleteThenImportWithOnlineIDMismatch(bool set)
{
// unfortunately for the time being we need to reference osu.Framework.Desktop for a game host here.
using (HeadlessGameHost host = new CleanRunHeadlessGameHost(set.ToString()))
using (HeadlessGameHost host = new CleanRunHeadlessGameHost($"{nameof(ImportBeatmapTest)}-{set}"))
{
try
{
var osu = loadOsu(host);
var osu = LoadOsuIntoHost(host);
var imported = await LoadOszIntoOsu(osu);
@ -440,11 +440,11 @@ namespace osu.Game.Tests.Beatmaps.IO
public async Task TestImportWithDuplicateBeatmapIDs()
{
// unfortunately for the time being we need to reference osu.Framework.Desktop for a game host here.
using (HeadlessGameHost host = new CleanRunHeadlessGameHost())
using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(ImportBeatmapTest)))
{
try
{
var osu = loadOsu(host);
var osu = LoadOsuIntoHost(host);
var metadata = new BeatmapMetadata
{
@ -496,15 +496,15 @@ namespace osu.Game.Tests.Beatmaps.IO
[Ignore("Binding IPC on Appveyor isn't working (port in use). Need to figure out why")]
public void TestImportOverIPC()
{
using (HeadlessGameHost host = new CleanRunHeadlessGameHost("host", true))
using (HeadlessGameHost client = new CleanRunHeadlessGameHost("client", true))
using (HeadlessGameHost host = new CleanRunHeadlessGameHost($"{nameof(ImportBeatmapTest)}-host", true))
using (HeadlessGameHost client = new CleanRunHeadlessGameHost($"{nameof(ImportBeatmapTest)}-client", true))
{
try
{
Assert.IsTrue(host.IsPrimaryInstance);
Assert.IsFalse(client.IsPrimaryInstance);
var osu = loadOsu(host);
var osu = LoadOsuIntoHost(host);
var temp = TestResources.GetTestBeatmapForImport();
@ -526,11 +526,11 @@ namespace osu.Game.Tests.Beatmaps.IO
[Test]
public async Task TestImportWhenFileOpen()
{
using (HeadlessGameHost host = new CleanRunHeadlessGameHost())
using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(ImportBeatmapTest)))
{
try
{
var osu = loadOsu(host);
var osu = LoadOsuIntoHost(host);
var temp = TestResources.GetTestBeatmapForImport();
using (File.OpenRead(temp))
await osu.Dependencies.Get<BeatmapManager>().Import(temp);
@ -548,11 +548,11 @@ namespace osu.Game.Tests.Beatmaps.IO
[Test]
public async Task TestImportWithDuplicateHashes()
{
using (HeadlessGameHost host = new CleanRunHeadlessGameHost())
using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(ImportBeatmapTest)))
{
try
{
var osu = loadOsu(host);
var osu = LoadOsuIntoHost(host);
var temp = TestResources.GetTestBeatmapForImport();
@ -590,11 +590,11 @@ namespace osu.Game.Tests.Beatmaps.IO
[Test]
public async Task TestImportNestedStructure()
{
using (HeadlessGameHost host = new CleanRunHeadlessGameHost())
using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(ImportBeatmapTest)))
{
try
{
var osu = loadOsu(host);
var osu = LoadOsuIntoHost(host);
var temp = TestResources.GetTestBeatmapForImport();
@ -635,11 +635,11 @@ namespace osu.Game.Tests.Beatmaps.IO
[Test]
public async Task TestImportWithIgnoredDirectoryInArchive()
{
using (HeadlessGameHost host = new CleanRunHeadlessGameHost())
using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(ImportBeatmapTest)))
{
try
{
var osu = loadOsu(host);
var osu = LoadOsuIntoHost(host);
var temp = TestResources.GetTestBeatmapForImport();
@ -689,11 +689,11 @@ namespace osu.Game.Tests.Beatmaps.IO
[Test]
public async Task TestUpdateBeatmapInfo()
{
using (HeadlessGameHost host = new CleanRunHeadlessGameHost())
using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(ImportBeatmapTest)))
{
try
{
var osu = loadOsu(host);
var osu = LoadOsuIntoHost(host);
var manager = osu.Dependencies.Get<BeatmapManager>();
var temp = TestResources.GetTestBeatmapForImport();
@ -719,11 +719,11 @@ namespace osu.Game.Tests.Beatmaps.IO
[Test]
public async Task TestUpdateBeatmapFile()
{
using (HeadlessGameHost host = new CleanRunHeadlessGameHost())
using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(ImportBeatmapTest)))
{
try
{
var osu = loadOsu(host);
var osu = LoadOsuIntoHost(host);
var manager = osu.Dependencies.Get<BeatmapManager>();
var temp = TestResources.GetTestBeatmapForImport();
@ -761,11 +761,11 @@ namespace osu.Game.Tests.Beatmaps.IO
[Test]
public void TestCreateNewEmptyBeatmap()
{
using (HeadlessGameHost host = new CleanRunHeadlessGameHost())
using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(ImportBeatmapTest)))
{
try
{
var osu = loadOsu(host);
var osu = LoadOsuIntoHost(host);
var manager = osu.Dependencies.Get<BeatmapManager>();
var working = manager.CreateNew(new OsuRuleset().RulesetInfo, User.SYSTEM_USER);
@ -788,11 +788,11 @@ namespace osu.Game.Tests.Beatmaps.IO
[Test]
public void TestCreateNewBeatmapWithObject()
{
using (HeadlessGameHost host = new CleanRunHeadlessGameHost())
using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(ImportBeatmapTest)))
{
try
{
var osu = loadOsu(host);
var osu = LoadOsuIntoHost(host);
var manager = osu.Dependencies.Get<BeatmapManager>();
var working = manager.CreateNew(new OsuRuleset().RulesetInfo, User.SYSTEM_USER);
@ -863,14 +863,6 @@ namespace osu.Game.Tests.Beatmaps.IO
Assert.AreEqual(expected, osu.Dependencies.Get<FileStore>().QueryFiles(f => f.ReferenceCount == 1).Count());
}
private OsuGameBase loadOsu(GameHost host)
{
var osu = new OsuGameBase();
Task.Run(() => host.Run(osu));
waitForOrAssert(() => osu.IsLoaded, @"osu! failed to start in a reasonable amount of time");
return osu;
}
private static void ensureLoaded(OsuGameBase osu, int timeout = 60000)
{
IEnumerable<BeatmapSetInfo> resultSets = null;

View File

@ -4,18 +4,15 @@
using System;
using System.IO;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Platform;
using osu.Game.Collections;
using osu.Game.Tests.Resources;
namespace osu.Game.Tests.Collections.IO
{
[TestFixture]
public class ImportCollectionsTest
public class ImportCollectionsTest : ImportTest
{
[Test]
public async Task TestImportEmptyDatabase()
@ -24,7 +21,7 @@ namespace osu.Game.Tests.Collections.IO
{
try
{
var osu = loadOsu(host);
var osu = LoadOsuIntoHost(host);
await osu.CollectionManager.Import(new MemoryStream());
@ -44,7 +41,7 @@ namespace osu.Game.Tests.Collections.IO
{
try
{
var osu = loadOsu(host);
var osu = LoadOsuIntoHost(host);
await osu.CollectionManager.Import(TestResources.OpenResource("Collections/collections.db"));
@ -70,7 +67,7 @@ namespace osu.Game.Tests.Collections.IO
{
try
{
var osu = loadOsu(host, true);
var osu = LoadOsuIntoHost(host, true);
await osu.CollectionManager.Import(TestResources.OpenResource("Collections/collections.db"));
@ -101,7 +98,7 @@ namespace osu.Game.Tests.Collections.IO
{
AppDomain.CurrentDomain.UnhandledException += setException;
var osu = loadOsu(host, true);
var osu = LoadOsuIntoHost(host, true);
using (var ms = new MemoryStream())
{
@ -135,7 +132,7 @@ namespace osu.Game.Tests.Collections.IO
{
try
{
var osu = loadOsu(host, true);
var osu = LoadOsuIntoHost(host, true);
await osu.CollectionManager.Import(TestResources.OpenResource("Collections/collections.db"));
@ -156,7 +153,7 @@ namespace osu.Game.Tests.Collections.IO
{
try
{
var osu = loadOsu(host, true);
var osu = LoadOsuIntoHost(host, true);
Assert.That(osu.CollectionManager.Collections.Count, Is.EqualTo(2));
@ -172,50 +169,5 @@ namespace osu.Game.Tests.Collections.IO
}
}
}
private TestOsuGameBase loadOsu(GameHost host, bool withBeatmap = false)
{
var osu = new TestOsuGameBase(withBeatmap);
#pragma warning disable 4014
Task.Run(() => host.Run(osu));
#pragma warning restore 4014
waitForOrAssert(() => osu.IsLoaded, @"osu! failed to start in a reasonable amount of time");
return osu;
}
private void waitForOrAssert(Func<bool> result, string failureMessage, int timeout = 60000)
{
Task task = Task.Run(() =>
{
while (!result()) Thread.Sleep(200);
});
Assert.IsTrue(task.Wait(timeout), failureMessage);
}
private class TestOsuGameBase : OsuGameBase
{
public CollectionManager CollectionManager { get; private set; }
private readonly bool withBeatmap;
public TestOsuGameBase(bool withBeatmap)
{
this.withBeatmap = withBeatmap;
}
[BackgroundDependencyLoader]
private void load()
{
// Beatmap must be imported before the collection manager is loaded.
if (withBeatmap)
BeatmapManager.Import(TestResources.GetTestBeatmapForImport()).Wait();
AddInternal(CollectionManager = new CollectionManager(Storage));
}
}
}
}

View File

@ -0,0 +1,66 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System;
using System.Threading;
using System.Threading.Tasks;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Platform;
using osu.Game.Collections;
using osu.Game.Tests.Resources;
namespace osu.Game.Tests
{
public abstract class ImportTest
{
protected virtual TestOsuGameBase LoadOsuIntoHost(GameHost host, bool withBeatmap = false)
{
var osu = new TestOsuGameBase(withBeatmap);
Task.Run(() => host.Run(osu));
waitForOrAssert(() => osu.IsLoaded, @"osu! failed to start in a reasonable amount of time");
bool ready = false;
// wait for two update frames to be executed. this ensures that all components have had a change to run LoadComplete and hopefully avoid
// database access (GlobalActionContainer is one to do this).
host.UpdateThread.Scheduler.Add(() => host.UpdateThread.Scheduler.Add(() => ready = true));
waitForOrAssert(() => ready, @"osu! failed to start in a reasonable amount of time");
return osu;
}
private void waitForOrAssert(Func<bool> result, string failureMessage, int timeout = 60000)
{
Task task = Task.Run(() =>
{
while (!result()) Thread.Sleep(200);
});
Assert.IsTrue(task.Wait(timeout), failureMessage);
}
public class TestOsuGameBase : OsuGameBase
{
public CollectionManager CollectionManager { get; private set; }
private readonly bool withBeatmap;
public TestOsuGameBase(bool withBeatmap)
{
this.withBeatmap = withBeatmap;
}
[BackgroundDependencyLoader]
private void load()
{
// Beatmap must be imported before the collection manager is loaded.
if (withBeatmap)
BeatmapManager.Import(TestResources.GetTestBeatmapForImport()).Wait();
AddInternal(CollectionManager = new CollectionManager(Storage));
}
}
}
}

View File

@ -4,8 +4,7 @@
using System;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Runtime.CompilerServices;
using NUnit.Framework;
using osu.Framework;
using osu.Framework.Allocation;
@ -17,18 +16,18 @@ using osu.Game.IO;
namespace osu.Game.Tests.NonVisual
{
[TestFixture]
public class CustomDataDirectoryTest
public class CustomDataDirectoryTest : ImportTest
{
[Test]
public void TestDefaultDirectory()
{
using (HeadlessGameHost host = new CustomTestHeadlessGameHost(nameof(TestDefaultDirectory)))
using (var host = new CustomTestHeadlessGameHost())
{
try
{
string defaultStorageLocation = getDefaultLocationFor(nameof(TestDefaultDirectory));
var osu = loadOsu(host);
var osu = LoadOsuIntoHost(host);
var storage = osu.Dependencies.Get<Storage>();
Assert.That(storage.GetFullPath("."), Is.EqualTo(defaultStorageLocation));
@ -45,14 +44,14 @@ namespace osu.Game.Tests.NonVisual
{
string customPath = prepareCustomPath();
using (var host = new CustomTestHeadlessGameHost(nameof(TestCustomDirectory)))
using (var host = new CustomTestHeadlessGameHost())
{
using (var storageConfig = new StorageConfigManager(host.InitialStorage))
storageConfig.Set(StorageConfig.FullPath, customPath);
try
{
var osu = loadOsu(host);
var osu = LoadOsuIntoHost(host);
// switch to DI'd storage
var storage = osu.Dependencies.Get<Storage>();
@ -71,14 +70,14 @@ namespace osu.Game.Tests.NonVisual
{
string customPath = prepareCustomPath();
using (var host = new CustomTestHeadlessGameHost(nameof(TestSubDirectoryLookup)))
using (var host = new CustomTestHeadlessGameHost())
{
using (var storageConfig = new StorageConfigManager(host.InitialStorage))
storageConfig.Set(StorageConfig.FullPath, customPath);
try
{
var osu = loadOsu(host);
var osu = LoadOsuIntoHost(host);
// switch to DI'd storage
var storage = osu.Dependencies.Get<Storage>();
@ -104,13 +103,13 @@ namespace osu.Game.Tests.NonVisual
{
string customPath = prepareCustomPath();
using (HeadlessGameHost host = new CustomTestHeadlessGameHost(nameof(TestMigration)))
using (var host = new CustomTestHeadlessGameHost())
{
try
{
string defaultStorageLocation = getDefaultLocationFor(nameof(TestMigration));
var osu = loadOsu(host);
var osu = LoadOsuIntoHost(host);
var storage = osu.Dependencies.Get<Storage>();
// Store the current storage's path. We'll need to refer to this for assertions in the original directory after the migration completes.
@ -165,11 +164,11 @@ namespace osu.Game.Tests.NonVisual
string customPath = prepareCustomPath();
string customPath2 = prepareCustomPath("-2");
using (HeadlessGameHost host = new CustomTestHeadlessGameHost(nameof(TestMigrationBetweenTwoTargets)))
using (var host = new CustomTestHeadlessGameHost())
{
try
{
var osu = loadOsu(host);
var osu = LoadOsuIntoHost(host);
const string database_filename = "client.db";
@ -194,11 +193,11 @@ namespace osu.Game.Tests.NonVisual
{
string customPath = prepareCustomPath();
using (HeadlessGameHost host = new CustomTestHeadlessGameHost(nameof(TestMigrationToSameTargetFails)))
using (var host = new CustomTestHeadlessGameHost())
{
try
{
var osu = loadOsu(host);
var osu = LoadOsuIntoHost(host);
Assert.DoesNotThrow(() => osu.Migrate(customPath));
Assert.Throws<ArgumentException>(() => osu.Migrate(customPath));
@ -215,11 +214,11 @@ namespace osu.Game.Tests.NonVisual
{
string customPath = prepareCustomPath();
using (HeadlessGameHost host = new CustomTestHeadlessGameHost(nameof(TestMigrationToNestedTargetFails)))
using (var host = new CustomTestHeadlessGameHost())
{
try
{
var osu = loadOsu(host);
var osu = LoadOsuIntoHost(host);
Assert.DoesNotThrow(() => osu.Migrate(customPath));
@ -244,11 +243,11 @@ namespace osu.Game.Tests.NonVisual
{
string customPath = prepareCustomPath();
using (HeadlessGameHost host = new CustomTestHeadlessGameHost(nameof(TestMigrationToSeeminglyNestedTarget)))
using (var host = new CustomTestHeadlessGameHost())
{
try
{
var osu = loadOsu(host);
var osu = LoadOsuIntoHost(host);
Assert.DoesNotThrow(() => osu.Migrate(customPath));
@ -268,25 +267,6 @@ namespace osu.Game.Tests.NonVisual
}
}
private OsuGameBase loadOsu(GameHost host)
{
var osu = new OsuGameBase();
Task.Run(() => host.Run(osu));
waitForOrAssert(() => osu.IsLoaded, @"osu! failed to start in a reasonable amount of time");
return osu;
}
private static void waitForOrAssert(Func<bool> result, string failureMessage, int timeout = 60000)
{
Task task = Task.Run(() =>
{
while (!result()) Thread.Sleep(200);
});
Assert.IsTrue(task.Wait(timeout), failureMessage);
}
private static string getDefaultLocationFor(string testTypeName)
{
string path = Path.Combine(RuntimeInfo.StartupDirectory, "headless", testTypeName);
@ -307,14 +287,14 @@ namespace osu.Game.Tests.NonVisual
return path;
}
public class CustomTestHeadlessGameHost : HeadlessGameHost
public class CustomTestHeadlessGameHost : CleanRunHeadlessGameHost
{
public Storage InitialStorage { get; }
public CustomTestHeadlessGameHost(string name)
: base(name)
public CustomTestHeadlessGameHost([CallerMemberName] string callingMethodName = @"")
: base(callingMethodName: callingMethodName)
{
string defaultStorageLocation = getDefaultLocationFor(name);
string defaultStorageLocation = getDefaultLocationFor(callingMethodName);
InitialStorage = new DesktopStorage(defaultStorageLocation, this);
InitialStorage.DeleteDirectory(string.Empty);

View File

@ -5,7 +5,6 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using NUnit.Framework;
using osu.Framework.Allocation;
@ -17,12 +16,11 @@ using osu.Game.Rulesets.Osu;
using osu.Game.Rulesets.Osu.Mods;
using osu.Game.Rulesets.Scoring;
using osu.Game.Scoring;
using osu.Game.Tests.Resources;
using osu.Game.Users;
namespace osu.Game.Tests.Scores.IO
{
public class ImportScoreTest
public class ImportScoreTest : ImportTest
{
[Test]
public async Task TestBasicImport()
@ -31,7 +29,7 @@ namespace osu.Game.Tests.Scores.IO
{
try
{
var osu = await loadOsu(host);
var osu = LoadOsuIntoHost(host, true);
var toImport = new ScoreInfo
{
@ -45,7 +43,7 @@ namespace osu.Game.Tests.Scores.IO
OnlineScoreID = 12345,
};
var imported = await loadIntoOsu(osu, toImport);
var imported = await loadScoreIntoOsu(osu, toImport);
Assert.AreEqual(toImport.Rank, imported.Rank);
Assert.AreEqual(toImport.TotalScore, imported.TotalScore);
@ -70,14 +68,14 @@ namespace osu.Game.Tests.Scores.IO
{
try
{
var osu = await loadOsu(host);
var osu = LoadOsuIntoHost(host, true);
var toImport = new ScoreInfo
{
Mods = new Mod[] { new OsuModHardRock(), new OsuModDoubleTime() },
};
var imported = await loadIntoOsu(osu, toImport);
var imported = await loadScoreIntoOsu(osu, toImport);
Assert.IsTrue(imported.Mods.Any(m => m is OsuModHardRock));
Assert.IsTrue(imported.Mods.Any(m => m is OsuModDoubleTime));
@ -96,7 +94,7 @@ namespace osu.Game.Tests.Scores.IO
{
try
{
var osu = await loadOsu(host);
var osu = LoadOsuIntoHost(host, true);
var toImport = new ScoreInfo
{
@ -107,7 +105,7 @@ namespace osu.Game.Tests.Scores.IO
}
};
var imported = await loadIntoOsu(osu, toImport);
var imported = await loadScoreIntoOsu(osu, toImport);
Assert.AreEqual(toImport.Statistics[HitResult.Perfect], imported.Statistics[HitResult.Perfect]);
Assert.AreEqual(toImport.Statistics[HitResult.Miss], imported.Statistics[HitResult.Miss]);
@ -126,7 +124,7 @@ namespace osu.Game.Tests.Scores.IO
{
try
{
var osu = await loadOsu(host);
var osu = LoadOsuIntoHost(host, true);
var toImport = new ScoreInfo
{
@ -138,7 +136,7 @@ namespace osu.Game.Tests.Scores.IO
}
};
var imported = await loadIntoOsu(osu, toImport);
var imported = await loadScoreIntoOsu(osu, toImport);
var beatmapManager = osu.Dependencies.Get<BeatmapManager>();
var scoreManager = osu.Dependencies.Get<ScoreManager>();
@ -146,7 +144,7 @@ namespace osu.Game.Tests.Scores.IO
beatmapManager.Delete(beatmapManager.QueryBeatmapSet(s => s.Beatmaps.Any(b => b.ID == imported.Beatmap.ID)));
Assert.That(scoreManager.Query(s => s.ID == imported.ID).DeletePending, Is.EqualTo(true));
var secondImport = await loadIntoOsu(osu, imported);
var secondImport = await loadScoreIntoOsu(osu, imported);
Assert.That(secondImport, Is.Null);
}
finally
@ -163,9 +161,9 @@ namespace osu.Game.Tests.Scores.IO
{
try
{
var osu = await loadOsu(host);
var osu = LoadOsuIntoHost(host, true);
await loadIntoOsu(osu, new ScoreInfo { OnlineScoreID = 2 }, new TestArchiveReader());
await loadScoreIntoOsu(osu, new ScoreInfo { OnlineScoreID = 2 }, new TestArchiveReader());
var scoreManager = osu.Dependencies.Get<ScoreManager>();
@ -179,7 +177,7 @@ namespace osu.Game.Tests.Scores.IO
}
}
private async Task<ScoreInfo> loadIntoOsu(OsuGameBase osu, ScoreInfo score, ArchiveReader archive = null)
private async Task<ScoreInfo> loadScoreIntoOsu(OsuGameBase osu, ScoreInfo score, ArchiveReader archive = null)
{
var beatmapManager = osu.Dependencies.Get<BeatmapManager>();
@ -192,33 +190,6 @@ namespace osu.Game.Tests.Scores.IO
return scoreManager.GetAllUsableScores().FirstOrDefault();
}
private async Task<OsuGameBase> loadOsu(GameHost host)
{
var osu = new OsuGameBase();
#pragma warning disable 4014
Task.Run(() => host.Run(osu));
#pragma warning restore 4014
waitForOrAssert(() => osu.IsLoaded, @"osu! failed to start in a reasonable amount of time");
var beatmapFile = TestResources.GetTestBeatmapForImport();
var beatmapManager = osu.Dependencies.Get<BeatmapManager>();
await beatmapManager.Import(beatmapFile);
return osu;
}
private void waitForOrAssert(Func<bool> result, string failureMessage, int timeout = 60000)
{
Task task = Task.Run(() =>
{
while (!result()) Thread.Sleep(200);
});
Assert.IsTrue(task.Wait(timeout), failureMessage);
}
private class TestArchiveReader : ArchiveReader
{
public TestArchiveReader()

View File

@ -0,0 +1,147 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Platform;
using osu.Game.IO.Archives;
using osu.Game.Skinning;
using SharpCompress.Archives.Zip;
namespace osu.Game.Tests.Skins.IO
{
public class ImportSkinTest : ImportTest
{
[Test]
public async Task TestBasicImport()
{
using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(ImportSkinTest)))
{
try
{
var osu = LoadOsuIntoHost(host);
var imported = await loadSkinIntoOsu(osu, new ZipArchiveReader(createOsk("test skin", "skinner"), "skin.osk"));
Assert.That(imported.Name, Is.EqualTo("test skin"));
Assert.That(imported.Creator, Is.EqualTo("skinner"));
}
finally
{
host.Exit();
}
}
}
[Test]
public async Task TestImportTwiceWithSameMetadata()
{
using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(ImportSkinTest)))
{
try
{
var osu = LoadOsuIntoHost(host);
var imported = await loadSkinIntoOsu(osu, new ZipArchiveReader(createOsk("test skin", "skinner"), "skin.osk"));
var imported2 = await loadSkinIntoOsu(osu, new ZipArchiveReader(createOsk("test skin", "skinner"), "skin2.osk"));
Assert.That(imported2.ID, Is.Not.EqualTo(imported.ID));
Assert.That(osu.Dependencies.Get<SkinManager>().GetAllUserSkins().Count, Is.EqualTo(1));
// the first should be overwritten by the second import.
Assert.That(osu.Dependencies.Get<SkinManager>().GetAllUserSkins().First().Files.First().FileInfoID, Is.EqualTo(imported2.Files.First().FileInfoID));
}
finally
{
host.Exit();
}
}
}
[Test]
public async Task TestImportTwiceWithNoMetadata()
{
using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(ImportSkinTest)))
{
try
{
var osu = LoadOsuIntoHost(host);
// if a user downloads two skins that do have skin.ini files but don't have any creator metadata in the skin.ini, they should both import separately just for safety.
var imported = await loadSkinIntoOsu(osu, new ZipArchiveReader(createOsk(string.Empty, string.Empty), "download.osk"));
var imported2 = await loadSkinIntoOsu(osu, new ZipArchiveReader(createOsk(string.Empty, string.Empty), "download.osk"));
Assert.That(imported2.ID, Is.Not.EqualTo(imported.ID));
Assert.That(osu.Dependencies.Get<SkinManager>().GetAllUserSkins().Count, Is.EqualTo(2));
Assert.That(osu.Dependencies.Get<SkinManager>().GetAllUserSkins().First().Files.First().FileInfoID, Is.EqualTo(imported.Files.First().FileInfoID));
Assert.That(osu.Dependencies.Get<SkinManager>().GetAllUserSkins().Last().Files.First().FileInfoID, Is.EqualTo(imported2.Files.First().FileInfoID));
}
finally
{
host.Exit();
}
}
}
[Test]
public async Task TestImportTwiceWithDifferentMetadata()
{
using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(ImportSkinTest)))
{
try
{
var osu = LoadOsuIntoHost(host);
var imported = await loadSkinIntoOsu(osu, new ZipArchiveReader(createOsk("test skin v2", "skinner"), "skin.osk"));
var imported2 = await loadSkinIntoOsu(osu, new ZipArchiveReader(createOsk("test skin v2.1", "skinner"), "skin2.osk"));
Assert.That(imported2.ID, Is.Not.EqualTo(imported.ID));
Assert.That(osu.Dependencies.Get<SkinManager>().GetAllUserSkins().Count, Is.EqualTo(2));
Assert.That(osu.Dependencies.Get<SkinManager>().GetAllUserSkins().First().Files.First().FileInfoID, Is.EqualTo(imported.Files.First().FileInfoID));
Assert.That(osu.Dependencies.Get<SkinManager>().GetAllUserSkins().Last().Files.First().FileInfoID, Is.EqualTo(imported2.Files.First().FileInfoID));
}
finally
{
host.Exit();
}
}
}
private MemoryStream createOsk(string name, string author)
{
var zipStream = new MemoryStream();
using var zip = ZipArchive.Create();
zip.AddEntry("skin.ini", generateSkinIni(name, author));
zip.SaveTo(zipStream);
return zipStream;
}
private MemoryStream generateSkinIni(string name, string author)
{
var stream = new MemoryStream();
var writer = new StreamWriter(stream);
writer.WriteLine("[General]");
writer.WriteLine($"Name: {name}");
writer.WriteLine($"Author: {author}");
writer.WriteLine();
writer.WriteLine($"# unique {Guid.NewGuid()}");
writer.Flush();
return stream;
}
private async Task<SkinInfo> loadSkinIntoOsu(OsuGameBase osu, ArchiveReader archive = null)
{
var skinManager = osu.Dependencies.Get<SkinManager>();
return await skinManager.Import(archive);
}
}
}

View File

@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using NUnit.Framework;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
@ -276,7 +277,7 @@ namespace osu.Game.Tests.Visual.Gameplay
public override bool CanConvert() => true;
protected override IEnumerable<TestHitObject> ConvertHitObject(HitObject original, IBeatmap beatmap)
protected override IEnumerable<TestHitObject> ConvertHitObject(HitObject original, IBeatmap beatmap, CancellationToken cancellationToken)
{
yield return new TestHitObject
{

View File

@ -74,6 +74,13 @@ namespace osu.Game.Tests.Visual.Navigation
private void returnToMenu()
{
// if we don't pause, there's a chance the track may change at the main menu out of our control (due to reaching the end of the track).
AddStep("pause audio", () =>
{
if (Game.MusicController.IsPlaying)
Game.MusicController.TogglePause();
});
AddStep("return to menu", () => Game.ScreenStack.CurrentScreen.Exit());
AddUntilStep("wait for menu", () => Game.ScreenStack.CurrentScreen is MainMenu);
}

View File

@ -110,6 +110,13 @@ namespace osu.Game.Tests.Visual.Navigation
private void returnToMenu()
{
// if we don't pause, there's a chance the track may change at the main menu out of our control (due to reaching the end of the track).
AddStep("pause audio", () =>
{
if (Game.MusicController.IsPlaying)
Game.MusicController.TogglePause();
});
AddStep("return to menu", () => Game.ScreenStack.CurrentScreen.Exit());
AddUntilStep("wait for menu", () => Game.ScreenStack.CurrentScreen is MainMenu);
}