Improve robustness by always creating a new file

This commit is contained in:
smoogipoo 2020-01-09 19:42:47 +09:00
parent 000fc836b2
commit b592b6d80d
2 changed files with 57 additions and 19 deletions

View File

@ -11,14 +11,10 @@
using osu.Framework.Platform;
using osu.Game.IPC;
using osu.Framework.Allocation;
using osu.Framework.Extensions;
using osu.Framework.IO.Stores;
using osu.Framework.Logging;
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.Formats;
using osu.Game.Database;
using osu.Game.IO;
using osu.Game.IO.Archives;
using osu.Game.Rulesets.Osu.Objects;
using osu.Game.Tests.Resources;
using SharpCompress.Archives;
@ -559,9 +555,9 @@ public async Task TestImportWithIgnoredDirectoryInArchive()
}
[Test]
public async Task TestUpdateBeatmapInfoContents()
public async Task TestUpdateBeatmapInfo()
{
using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(TestUpdateBeatmapInfoContents)))
using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(TestUpdateBeatmapInfo)))
{
try
{
@ -589,9 +585,9 @@ public async Task TestUpdateBeatmapInfoContents()
}
[Test]
public async Task TestUpdateBeatmapFileContents()
public async Task TestUpdateBeatmapFile()
{
using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(TestUpdateBeatmapFileContents)))
using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(TestUpdateBeatmapFile)))
{
try
{
@ -617,7 +613,51 @@ public async Task TestUpdateBeatmapFileContents()
stream.Seek(0, SeekOrigin.Begin);
manager.UpdateFile(fileToUpdate, stream);
manager.UpdateFile(setToUpdate, fileToUpdate, stream);
}
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));
}
finally
{
host.Exit();
}
}
}
[Test]
public async Task TestAddFile()
{
using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(TestAddFile)))
{
try
{
var osu = loadOsu(host);
var manager = osu.Dependencies.Get<BeatmapManager>();
var temp = TestResources.GetTestBeatmapForImport();
await osu.Dependencies.Get<BeatmapManager>().Import(temp);
BeatmapSetInfo setToUpdate = manager.GetAllUsableBeatmapSets()[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));
using (var stream = new MemoryStream())
{
using (var writer = new StreamWriter(stream, leaveOpen: true))
{
beatmapToUpdate.HitObjects.Clear();
beatmapToUpdate.HitObjects.Add(new HitCircle { StartTime = 5000 });
new LegacyBeatmapEncoder(beatmapToUpdate).Encode(writer);
}
stream.Seek(0, SeekOrigin.Begin);
manager.UpdateFile(setToUpdate, fileToUpdate, stream);
}
Beatmap updatedBeatmap = (Beatmap)manager.GetWorkingBeatmap(manager.QueryBeatmap(b => b.ID == beatmapToUpdate.BeatmapInfo.ID)).Beatmap;

View File

@ -364,20 +364,18 @@ void rollback()
return item;
}, cancellationToken, TaskCreationOptions.HideScheduler, import_scheduler).Unwrap();
public void UpdateFile(TFileModel file, Stream contents)
public void UpdateFile(TModel model, TFileModel file, Stream contents)
{
using (ContextFactory.GetForWrite()) // used to share a context for full import. keep in mind this will block all writes.
{
var existingModels = ModelStore.ConsumableItems.Where(b => b.Files.Any(f => f.FileInfoID == file.FileInfoID)).ToList();
model.Files.Remove(file);
model.Files.Add(new TFileModel
{
Filename = file.Filename,
FileInfo = Files.Add(contents)
});
if (existingModels.Count == 0)
throw new InvalidOperationException($"Cannot update files of models not contained by this {nameof(ArchiveModelManager<TModel, TFileModel>)}.");
using (var stream = Files.Storage.GetStream(file.FileInfo.StoragePath, FileAccess.Write, FileMode.Create))
contents.CopyTo(stream);
foreach (var model in existingModels)
Update(model);
Update(model);
}
}