Exemple #1
0
        public async Task TestImportNestedStructure()
        {
            using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(ImportBeatmapTest)))
            {
                try
                {
                    var osu = LoadOsuIntoHost(host);

                    var temp = TestResources.GetTestBeatmapForImport();

                    string extractedFolder = $"{temp}_extracted";
                    string subfolder       = Path.Combine(extractedFolder, "subfolder");

                    Directory.CreateDirectory(subfolder);

                    try
                    {
                        using (var zip = ZipArchive.Open(temp))
                            zip.WriteToDirectory(subfolder);

                        using (var zip = ZipArchive.Create())
                        {
                            zip.AddAllFromDirectory(extractedFolder);
                            zip.SaveTo(temp, new ZipWriterOptions(CompressionType.Deflate));
                        }

                        var imported = await osu.Dependencies.Get <BeatmapManager>().Import(temp);

                        ensureLoaded(osu);

                        Assert.IsFalse(imported.Files.Any(f => f.Filename.Contains("subfolder")), "Files contain common subfolder");
                    }
                    finally
                    {
                        Directory.Delete(extractedFolder, true);
                    }
                }
                finally
                {
                    host.Exit();
                }
            }
        }
Exemple #2
0
        public async Task TestUpdateBeatmapFile()
        {
            using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(ImportBeatmapTest)))
            {
                try
                {
                    var osu     = LoadOsuIntoHost(host);
                    var manager = osu.Dependencies.Get <BeatmapManager>();

                    var temp = TestResources.GetTestBeatmapForImport();
                    await osu.Dependencies.Get <BeatmapManager>().Import(temp);

                    BeatmapSetInfo setToUpdate = manager.GetAllUsableBeatmapSets()[0];

                    var                beatmapInfo     = setToUpdate.Beatmaps.First(b => b.RulesetID == 0);
                    Beatmap            beatmapToUpdate = (Beatmap)manager.GetWorkingBeatmap(setToUpdate.Beatmaps.First(b => b.RulesetID == 0)).Beatmap;
                    BeatmapSetFileInfo fileToUpdate    = setToUpdate.Files.First(f => beatmapToUpdate.BeatmapInfo.Path.Contains(f.Filename));

                    string oldMd5Hash = beatmapToUpdate.BeatmapInfo.MD5Hash;

                    beatmapToUpdate.HitObjects.Clear();
                    beatmapToUpdate.HitObjects.Add(new HitCircle {
                        StartTime = 5000
                    });

                    manager.Save(beatmapInfo, beatmapToUpdate);

                    // Check that the old file reference has been removed
                    Assert.That(manager.QueryBeatmapSet(s => s.ID == setToUpdate.ID).Files.All(f => f.ID != fileToUpdate.ID));

                    // Check that the new file is referenced correctly by attempting a retrieval
                    Beatmap updatedBeatmap = (Beatmap)manager.GetWorkingBeatmap(manager.QueryBeatmap(b => b.ID == beatmapToUpdate.BeatmapInfo.ID)).Beatmap;
                    Assert.That(updatedBeatmap.HitObjects.Count, Is.EqualTo(1));
                    Assert.That(updatedBeatmap.HitObjects[0].StartTime, Is.EqualTo(5000));
                    Assert.That(updatedBeatmap.BeatmapInfo.MD5Hash, Is.Not.EqualTo(oldMd5Hash));
                }
                finally
                {
                    host.Exit();
                }
            }
        }
Exemple #3
0
 public async Task TestImportWhenFileOpen()
 {
     using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(ImportBeatmapTest)))
     {
         try
         {
             var osu  = LoadOsuIntoHost(host);
             var temp = TestResources.GetTestBeatmapForImport();
             using (File.OpenRead(temp))
                 await osu.Dependencies.Get <BeatmapManager>().Import(temp);
             ensureLoaded(osu);
             File.Delete(temp);
             Assert.IsFalse(File.Exists(temp), "We likely held a read lock on the file when we shouldn't");
         }
         finally
         {
             host.Exit();
         }
     }
 }
Exemple #4
0
        public void TestUpdateBeatmapInfo()
        {
            RunTestWithRealmAsync(async(realmFactory, storage) =>
            {
                using var importer = new BeatmapImporter(realmFactory, storage);
                using var store    = new RealmRulesetStore(realmFactory, storage);

                string?temp = TestResources.GetTestBeatmapForImport();
                await importer.Import(temp);

                // Update via the beatmap, not the beatmap info, to ensure correct linking
                RealmBeatmapSet setToUpdate = realmFactory.Context.All <RealmBeatmapSet>().First();

                var beatmapToUpdate = setToUpdate.Beatmaps.First();

                realmFactory.Context.Write(() => beatmapToUpdate.DifficultyName = "updated");

                RealmBeatmap updatedInfo = realmFactory.Context.All <RealmBeatmap>().First(b => b.ID == beatmapToUpdate.ID);
                Assert.That(updatedInfo.DifficultyName, Is.EqualTo("updated"));
            });
        }
Exemple #5
0
        private void load(GameHost host)
        {
            factory = new DatabaseContextFactory(LocalStorage);
            factory.ResetDatabase();

            using (var usage = factory.Get())
                usage.Migrate();

            factory.ResetDatabase();

            using (var usage = factory.Get())
                usage.Migrate();

            Dependencies.Cache(rulesets = new RulesetStore(factory));
            Dependencies.Cache(manager  = new BeatmapManager(LocalStorage, factory, rulesets, null, null, host, Beatmap.Default));
            Dependencies.Cache(new OsuConfigManager(LocalStorage));

            manager.Import(TestResources.GetTestBeatmapForImport());

            Beatmap.SetDefault();
        }
Exemple #6
0
        public void TestTrackerRespectsChecksum()
        {
            AddStep("allow importing", () => beatmaps.AllowImport.SetResult(true));
            AddStep("import beatmap", () => beatmaps.Import(testBeatmapFile).WaitSafely());
            addAvailabilityCheckStep("initially locally available", BeatmapAvailability.LocallyAvailable);

            AddStep("import altered beatmap", () =>
            {
                beatmaps.Import(TestResources.GetTestBeatmapForImport(true)).WaitSafely();
            });
            addAvailabilityCheckStep("state not downloaded", BeatmapAvailability.NotDownloaded);

            AddStep("recreate tracker", () => Child = availabilityTracker = new OnlinePlayBeatmapAvailabilityTracker
            {
                SelectedItem = { BindTarget = selectedItem }
            });
            addAvailabilityCheckStep("state not downloaded as well", BeatmapAvailability.NotDownloaded);

            AddStep("reimport original beatmap", () => beatmaps.Import(TestResources.GetQuickTestBeatmapForImport()).WaitSafely());
            addAvailabilityCheckStep("locally available after re-import", BeatmapAvailability.LocallyAvailable);
        }
Exemple #7
0
        public void TestImportNestedStructure()
        {
            RunTestWithRealmAsync(async(realmFactory, storage) =>
            {
                using var importer = new BeatmapImporter(realmFactory, storage);
                using var store    = new RealmRulesetStore(realmFactory, storage);

                string?temp = TestResources.GetTestBeatmapForImport();

                string extractedFolder = $"{temp}_extracted";
                string subfolder       = Path.Combine(extractedFolder, "subfolder");

                Directory.CreateDirectory(subfolder);

                try
                {
                    using (var zip = ZipArchive.Open(temp))
                        zip.WriteToDirectory(subfolder);

                    using (var zip = ZipArchive.Create())
                    {
                        zip.AddAllFromDirectory(extractedFolder);
                        zip.SaveTo(temp, new ZipWriterOptions(CompressionType.Deflate));
                    }

                    var imported = await importer.Import(new ImportTask(temp));

                    Assert.NotNull(imported);
                    Debug.Assert(imported != null);

                    ensureLoaded(realmFactory.Context);

                    Assert.IsFalse(imported.PerformRead(s => s.Files.Any(f => f.Filename.Contains("subfolder"))), "Files contain common subfolder");
                }
                finally
                {
                    Directory.Delete(extractedFolder, true);
                }
            });
        }
Exemple #8
0
        public async Task TestImportWithDuplicateHashes()
        {
            using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(ImportBeatmapTest)))
            {
                try
                {
                    var osu = LoadOsuIntoHost(host);

                    var temp = TestResources.GetTestBeatmapForImport();

                    string extractedFolder = $"{temp}_extracted";
                    Directory.CreateDirectory(extractedFolder);

                    try
                    {
                        using (var zip = ZipArchive.Open(temp))
                            zip.WriteToDirectory(extractedFolder);

                        using (var zip = ZipArchive.Create())
                        {
                            zip.AddAllFromDirectory(extractedFolder);
                            zip.AddEntry("duplicate.osu", Directory.GetFiles(extractedFolder, "*.osu").First());
                            zip.SaveTo(temp, new ZipWriterOptions(CompressionType.Deflate));
                        }

                        await osu.Dependencies.Get <BeatmapManager>().Import(temp);

                        ensureLoaded(osu);
                    }
                    finally
                    {
                        Directory.Delete(extractedFolder, true);
                    }
                }
                finally
                {
                    host.Exit();
                }
            }
        }
Exemple #9
0
        public void TestMusicNavigationActions()
        {
            Queue <(IWorkingBeatmap working, TrackChangeDirection changeDirection)> trackChangeQueue = null;

            // ensure we have at least two beatmaps available to identify the direction the music controller navigated to.
            AddRepeatStep("import beatmap", () => Game.BeatmapManager.Import(TestResources.CreateTestBeatmapSetInfo()), 5);

            AddStep("import beatmap with track", () =>
            {
                var setWithTrack = Game.BeatmapManager.Import(new ImportTask(TestResources.GetTestBeatmapForImport())).GetResultSafely();
                setWithTrack?.PerformRead(s =>
                {
                    Beatmap.Value = Game.BeatmapManager.GetWorkingBeatmap(s.Beatmaps.First());
                });
            });

            AddStep("bind to track change", () =>
            {
                trackChangeQueue = new Queue <(IWorkingBeatmap, TrackChangeDirection)>();
                Game.MusicController.TrackChanged += (working, changeDirection) => trackChangeQueue.Enqueue((working, changeDirection));
            });

            AddStep("seek track to 6 second", () => Game.MusicController.SeekTo(6000));
            AddUntilStep("wait for current time to update", () => Game.MusicController.CurrentTrack.CurrentTime > 5000);

            AddStep("press previous", () => globalActionContainer.TriggerPressed(GlobalAction.MusicPrev));
            AddAssert("no track change", () => trackChangeQueue.Count == 0);
            AddUntilStep("track restarted", () => Game.MusicController.CurrentTrack.CurrentTime < 5000);

            AddStep("press previous", () => globalActionContainer.TriggerPressed(GlobalAction.MusicPrev));
            AddAssert("track changed to previous", () =>
                      trackChangeQueue.Count == 1 &&
                      trackChangeQueue.Dequeue().changeDirection == TrackChangeDirection.Prev);

            AddStep("press next", () => globalActionContainer.TriggerPressed(GlobalAction.MusicNext));
            AddAssert("track changed to next", () =>
                      trackChangeQueue.Count == 1 &&
                      trackChangeQueue.Dequeue().changeDirection == TrackChangeDirection.Next);
        }
Exemple #10
0
        public void TestPrevTrackBehavior()
        {
            // ensure we have at least two beatmaps available.
            AddRepeatStep("import beatmap", () => manager.Import(new BeatmapSetInfo
            {
                Beatmaps = new List <BeatmapInfo>
                {
                    new BeatmapInfo
                    {
                        BaseDifficulty = new BeatmapDifficulty(),
                    }
                },
                Metadata = new BeatmapMetadata
                {
                    Artist = $"a test map {importId++}",
                    Title  = "title",
                }
            }).Wait(), 5);

            WorkingBeatmap currentBeatmap = null;

            AddStep("import beatmap with track", () =>
            {
                var setWithTrack = manager.Import(TestResources.GetTestBeatmapForImport()).Result;
                Beatmap.Value    = currentBeatmap = manager.GetWorkingBeatmap(setWithTrack.Beatmaps.First());
            });

            AddStep(@"Seek track to 6 second", () => musicController.SeekTo(6000));
            AddUntilStep(@"Wait for current time to update", () => musicController.CurrentTrack.CurrentTime > 5000);

            AddStep(@"Set previous", () => musicController.PreviousTrack());

            AddAssert(@"Check beatmap didn't change", () => currentBeatmap == Beatmap.Value);
            AddUntilStep("Wait for current time to update", () => musicController.CurrentTrack.CurrentTime < 5000);

            AddStep(@"Set previous", () => musicController.PreviousTrack());
            AddAssert(@"Check beatmap did change", () => currentBeatmap != Beatmap.Value);
        }
        public void TestAddAudioTrack()
        {
            AddAssert("switch track to real track", () =>
            {
                var setup = Editor.ChildrenOfType <SetupScreen>().First();

                var temp = TestResources.GetTestBeatmapForImport();

                string extractedFolder = $"{temp}_extracted";
                Directory.CreateDirectory(extractedFolder);

                using (var zip = ZipArchive.Open(temp))
                    zip.WriteToDirectory(extractedFolder);

                bool success = setup.ChangeAudioTrack(Path.Combine(extractedFolder, "03. Renatus - Soleily 192kbps.mp3"));

                File.Delete(temp);
                Directory.Delete(extractedFolder, true);

                return(success);
            });

            AddAssert("track length changed", () => Beatmap.Value.Track.Length > 60000);
        }
Exemple #12
0
        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(nameof(ImportBeatmapTest)))
            {
                try
                {
                    int itemAddRemoveFireCount = 0;
                    int loggedExceptionCount   = 0;

                    Logger.NewEntry += l =>
                    {
                        if (l.Target == LoggingTarget.Database && l.Exception != null)
                        {
                            Interlocked.Increment(ref loggedExceptionCount);
                        }
                    };

                    var osu     = LoadOsuIntoHost(host);
                    var manager = osu.Dependencies.Get <BeatmapManager>();

                    // ReSharper disable once AccessToModifiedClosure
                    manager.ItemUpdated.BindValueChanged(_ => Interlocked.Increment(ref itemAddRemoveFireCount));
                    manager.ItemRemoved.BindValueChanged(_ => Interlocked.Increment(ref itemAddRemoveFireCount));

                    var imported = await LoadOszIntoOsu(osu);

                    Assert.AreEqual(0, itemAddRemoveFireCount -= 1);

                    imported.Hash += "-changed";
                    manager.Update(imported);

                    Assert.AreEqual(0, itemAddRemoveFireCount -= 1);

                    checkBeatmapSetCount(osu, 1);
                    checkBeatmapCount(osu, 12);
                    checkSingleReferencedFileCount(osu, 18);

                    var brokenTempFilename = TestResources.GetTestBeatmapForImport();

                    MemoryStream brokenOsu = new MemoryStream();
                    MemoryStream brokenOsz = new MemoryStream(await File.ReadAllBytesAsync(brokenTempFilename));

                    File.Delete(brokenTempFilename);

                    using (var outStream = File.Open(brokenTempFilename, FileMode.CreateNew))
                        using (var zip = ZipArchive.Open(brokenOsz))
                        {
                            zip.AddEntry("broken.osu", brokenOsu, false);
                            zip.SaveTo(outStream, CompressionType.Deflate);
                        }

                    // this will trigger purging of the existing beatmap (online set id match) but should rollback due to broken osu.
                    try
                    {
                        await manager.Import(new ImportTask(brokenTempFilename));
                    }
                    catch
                    {
                    }

                    // no events should be fired in the case of a rollback.
                    Assert.AreEqual(0, itemAddRemoveFireCount);

                    checkBeatmapSetCount(osu, 1);
                    checkBeatmapCount(osu, 12);

                    checkSingleReferencedFileCount(osu, 18);

                    Assert.AreEqual(1, loggedExceptionCount);

                    File.Delete(brokenTempFilename);
                }
                finally
                {
                    host.Exit();
                }
            }
        }
 private void load(GameHost host, AudioManager audio)
 {
     Dependencies.Cache(rulesets = new RulesetStore(ContextFactory));
     Dependencies.Cache(beatmaps = new BeatmapManager(LocalStorage, ContextFactory, rulesets, null, audio, host, Beatmap.Default));
     beatmaps.Import(TestResources.GetTestBeatmapForImport(true)).Wait();
 }
Exemple #14
0
        public override void SetUpSteps()
        {
            AddStep("Prepare import beatmap", () => importFilename = TestResources.GetTestBeatmapForImport());

            base.SetUpSteps();
        }