From ad625ecc7a199e3f93a4e827312d07b4fbeee957 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 7 Sep 2020 22:10:12 +0900 Subject: [PATCH] Add collection IO tests --- .../Collections/IO/ImportCollectionsTest.cs | 215 ++++++++++++++++++ .../Resources/Collections/collections.db | Bin 0 -> 473 bytes .../Collections/BeatmapCollectionManager.cs | 22 +- 3 files changed, 232 insertions(+), 5 deletions(-) create mode 100644 osu.Game.Tests/Collections/IO/ImportCollectionsTest.cs create mode 100644 osu.Game.Tests/Resources/Collections/collections.db diff --git a/osu.Game.Tests/Collections/IO/ImportCollectionsTest.cs b/osu.Game.Tests/Collections/IO/ImportCollectionsTest.cs new file mode 100644 index 0000000000..7d772d3989 --- /dev/null +++ b/osu.Game.Tests/Collections/IO/ImportCollectionsTest.cs @@ -0,0 +1,215 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +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.Beatmaps; +using osu.Game.Collections; +using osu.Game.Tests.Resources; + +namespace osu.Game.Tests.Collections.IO +{ + [TestFixture] + public class ImportCollectionsTest + { + [Test] + public async Task TestImportEmptyDatabase() + { + using (HeadlessGameHost host = new CleanRunHeadlessGameHost("TestImportEmptyDatabase")) + { + try + { + var osu = await loadOsu(host); + + var collectionManager = osu.Dependencies.Get(); + await collectionManager.Import(new MemoryStream()); + + Assert.That(collectionManager.Collections.Count, Is.Zero); + } + finally + { + host.Exit(); + } + } + } + + [Test] + public async Task TestImportWithNoBeatmaps() + { + using (HeadlessGameHost host = new CleanRunHeadlessGameHost("TestImportWithNoBeatmaps")) + { + try + { + var osu = await loadOsu(host); + + var collectionManager = osu.Dependencies.Get(); + await collectionManager.Import(TestResources.OpenResource("Collections/collections.db")); + + Assert.That(collectionManager.Collections.Count, Is.EqualTo(2)); + + Assert.That(collectionManager.Collections[0].Name.Value, Is.EqualTo("First")); + Assert.That(collectionManager.Collections[0].Beatmaps.Count, Is.Zero); + + Assert.That(collectionManager.Collections[1].Name.Value, Is.EqualTo("Second")); + Assert.That(collectionManager.Collections[1].Beatmaps.Count, Is.Zero); + } + finally + { + host.Exit(); + } + } + } + + [Test] + public async Task TestImportWithBeatmaps() + { + using (HeadlessGameHost host = new CleanRunHeadlessGameHost("TestImportWithBeatmaps")) + { + try + { + var osu = await loadOsu(host, true); + + var collectionManager = osu.Dependencies.Get(); + await collectionManager.Import(TestResources.OpenResource("Collections/collections.db")); + + Assert.That(collectionManager.Collections.Count, Is.EqualTo(2)); + + Assert.That(collectionManager.Collections[0].Name.Value, Is.EqualTo("First")); + Assert.That(collectionManager.Collections[0].Beatmaps.Count, Is.EqualTo(1)); + + Assert.That(collectionManager.Collections[1].Name.Value, Is.EqualTo("Second")); + Assert.That(collectionManager.Collections[1].Beatmaps.Count, Is.EqualTo(12)); + } + finally + { + host.Exit(); + } + } + } + + [Test] + public async Task TestImportMalformedDatabase() + { + bool exceptionThrown = false; + UnhandledExceptionEventHandler setException = (_, __) => exceptionThrown = true; + + using (HeadlessGameHost host = new CleanRunHeadlessGameHost("TestImportMalformedDatabase")) + { + try + { + AppDomain.CurrentDomain.UnhandledException += setException; + + var osu = await loadOsu(host, true); + + var collectionManager = osu.Dependencies.Get(); + + using (var ms = new MemoryStream()) + { + using (var bw = new BinaryWriter(ms, Encoding.UTF8, true)) + { + for (int i = 0; i < 10000; i++) + bw.Write((byte)i); + } + + ms.Seek(0, SeekOrigin.Begin); + + await collectionManager.Import(ms); + } + + Assert.That(host.UpdateThread.Running, Is.True); + Assert.That(exceptionThrown, Is.False); + Assert.That(collectionManager.Collections.Count, Is.EqualTo(0)); + } + finally + { + host.Exit(); + AppDomain.CurrentDomain.UnhandledException -= setException; + } + } + } + + [Test] + public async Task TestSaveAndReload() + { + using (HeadlessGameHost host = new CleanRunHeadlessGameHost("TestSaveAndReload")) + { + try + { + var osu = await loadOsu(host, true); + + var collectionManager = osu.Dependencies.Get(); + await collectionManager.Import(TestResources.OpenResource("Collections/collections.db")); + + // Move first beatmap from second collection into the first. + collectionManager.Collections[0].Beatmaps.Add(collectionManager.Collections[1].Beatmaps[0]); + collectionManager.Collections[1].Beatmaps.RemoveAt(0); + + // Rename the second collecction. + collectionManager.Collections[1].Name.Value = "Another"; + } + finally + { + host.Exit(); + } + } + + using (HeadlessGameHost host = new HeadlessGameHost("TestSaveAndReload")) + { + try + { + var osu = await loadOsu(host, true); + + var collectionManager = osu.Dependencies.Get(); + + Assert.That(collectionManager.Collections.Count, Is.EqualTo(2)); + + Assert.That(collectionManager.Collections[0].Name.Value, Is.EqualTo("First")); + Assert.That(collectionManager.Collections[0].Beatmaps.Count, Is.EqualTo(2)); + + Assert.That(collectionManager.Collections[1].Name.Value, Is.EqualTo("Another")); + Assert.That(collectionManager.Collections[1].Beatmaps.Count, Is.EqualTo(11)); + } + finally + { + host.Exit(); + } + } + } + + private async Task loadOsu(GameHost host, bool withBeatmap = false) + { + 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"); + + if (withBeatmap) + { + var beatmapFile = TestResources.GetTestBeatmapForImport(); + var beatmapManager = osu.Dependencies.Get(); + await beatmapManager.Import(beatmapFile); + } + + return osu; + } + + private void waitForOrAssert(Func result, string failureMessage, int timeout = 60000) + { + Task task = Task.Run(() => + { + while (!result()) Thread.Sleep(200); + }); + + Assert.IsTrue(task.Wait(timeout), failureMessage); + } + } +} diff --git a/osu.Game.Tests/Resources/Collections/collections.db b/osu.Game.Tests/Resources/Collections/collections.db new file mode 100644 index 0000000000000000000000000000000000000000..83e1c0f10a9058f3f376e75d3b5a88f671a95f63 GIT binary patch literal 473 zcmah_%W0lL4E!CiFJFrIO3>=Ld+;?4qyjxw;7bCryL3}or-29rgV2mL^ZCk8-yV<0 z_59=Q&-=&I7rdJX!-hP)U7D7xkTeI>lFo6x{M`BbSAGAty`>hfB!!t?h{`*ueUU(z zwqLg>Kq9oOjOI0BLY+xkyAg0+_rhpwBocF}ptLdFxMa3XucLvnYP9pNF;*O~cDSX^ zm8A@4W6w#hixgKP0&(j^RSP^kU2@%VUNsbpr9-6>Ab1NHf^gOz*PS64xg(D-ELaUW z$6;(dB@EZi9CA)@46-aEqHY}+Vltepue&O_nhD)wo)}crPm*6o_5?jw{+sW8lH + return Task.Run(async () => { var storage = GetStableStorage(); if (storage.Exists(database_name)) { using (var stream = storage.GetStream(database_name)) - { - var collection = readCollections(stream); - Schedule(() => importCollections(collection)); - } + await Import(stream); } }); } + public async Task Import(Stream stream) => await Task.Run(async () => + { + var collection = readCollections(stream); + bool importCompleted = false; + + Schedule(() => + { + importCollections(collection); + importCompleted = true; + }); + + while (!IsDisposed && !importCompleted) + await Task.Delay(10); + }); + private void importCollections(List newCollections) { foreach (var newCol in newCollections)