LibHac/tests/LibHac.Tests/Fs/DirectorySaveDataFileSystemTests.cs
Alex Barney 44e4c7a311
Add some fssystem utility functions and use them in DirectorySaveDataFileSystem (#133)
* Accurately implement DirectorySaveDataFileSystem

* DirectorySaveDataFileSystem updates from FS 10.0
2020-05-12 13:17:06 -07:00

172 lines
6.5 KiB
C#

using LibHac.Common;
using LibHac.Fs;
using LibHac.FsSystem;
using LibHac.Tests.Fs.IFileSystemTestBase;
using Xunit;
namespace LibHac.Tests.Fs
{
public class DirectorySaveDataFileSystemTests : CommittableIFileSystemTests
{
protected override IFileSystem CreateFileSystem()
{
return CreateFileSystemInternal().saveFs;
}
protected override IReopenableFileSystemCreator GetFileSystemCreator()
{
return new DirectorySaveDataFileSystemCreator();
}
private class DirectorySaveDataFileSystemCreator : IReopenableFileSystemCreator
{
private IFileSystem _baseFileSystem { get; }
public DirectorySaveDataFileSystemCreator()
{
_baseFileSystem = new InMemoryFileSystem();
}
public IFileSystem Create()
{
DirectorySaveDataFileSystem.CreateNew(out DirectorySaveDataFileSystem saveFs, _baseFileSystem, true, true)
.ThrowIfFailure();
return saveFs;
}
}
private (IFileSystem baseFs, IFileSystem saveFs) CreateFileSystemInternal()
{
var baseFs = new InMemoryFileSystem();
DirectorySaveDataFileSystem.CreateNew(out DirectorySaveDataFileSystem saveFs, baseFs, true, true)
.ThrowIfFailure();
return (baseFs, saveFs);
}
[Fact]
public void CreateFile_CreatedInWorkingDirectory()
{
(IFileSystem baseFs, IFileSystem saveFs) = CreateFileSystemInternal();
saveFs.CreateFile("/file".ToU8Span(), 0, CreateFileOptions.None);
Assert.Success(baseFs.GetEntryType(out DirectoryEntryType type, "/1/file".ToU8Span()));
Assert.Equal(DirectoryEntryType.File, type);
}
[Fact]
public void CreateFile_NotCreatedInCommittedDirectory()
{
(IFileSystem baseFs, IFileSystem saveFs) = CreateFileSystemInternal();
saveFs.CreateFile("/file".ToU8Span(), 0, CreateFileOptions.None);
Assert.Result(ResultFs.PathNotFound, baseFs.GetEntryType(out _, "/0/file".ToU8Span()));
}
[Fact]
public void Commit_FileExistsInCommittedDirectory()
{
(IFileSystem baseFs, IFileSystem saveFs) = CreateFileSystemInternal();
saveFs.CreateFile("/file".ToU8Span(), 0, CreateFileOptions.None);
Assert.Success(saveFs.Commit());
Assert.Success(baseFs.GetEntryType(out DirectoryEntryType type, "/0/file".ToU8Span()));
Assert.Equal(DirectoryEntryType.File, type);
}
[Fact]
public void Rollback_FileDoesNotExistInBaseAfterRollback()
{
(IFileSystem baseFs, IFileSystem saveFs) = CreateFileSystemInternal();
saveFs.CreateFile("/file".ToU8Span(), 0, CreateFileOptions.None);
// Rollback should succeed
Assert.Success(saveFs.Rollback());
// Make sure all the files are gone
Assert.Result(ResultFs.PathNotFound, saveFs.GetEntryType(out _, "/file".ToU8Span()));
Assert.Result(ResultFs.PathNotFound, baseFs.GetEntryType(out _, "/0/file".ToU8Span()));
Assert.Result(ResultFs.PathNotFound, baseFs.GetEntryType(out _, "/1/file".ToU8Span()));
}
[Fact]
public void Rollback_DeletedFileIsRestoredInBaseAfterRollback()
{
(IFileSystem baseFs, IFileSystem saveFs) = CreateFileSystemInternal();
saveFs.CreateFile("/file".ToU8Span(), 0, CreateFileOptions.None);
saveFs.Commit();
saveFs.DeleteFile("/file".ToU8Span());
// Rollback should succeed
Assert.Success(saveFs.Rollback());
// Make sure all the files are restored
Assert.Success(saveFs.GetEntryType(out _, "/file".ToU8Span()));
Assert.Success(baseFs.GetEntryType(out _, "/0/file".ToU8Span()));
Assert.Success(baseFs.GetEntryType(out _, "/1/file".ToU8Span()));
}
[Fact]
public void Initialize_NormalState_UsesCommittedData()
{
var baseFs = new InMemoryFileSystem();
baseFs.CreateDirectory("/0".ToU8Span()).ThrowIfFailure();
baseFs.CreateDirectory("/1".ToU8Span()).ThrowIfFailure();
// Set the existing files before initializing the save FS
baseFs.CreateFile("/0/file1".ToU8Span(), 0, CreateFileOptions.None).ThrowIfFailure();
baseFs.CreateFile("/1/file2".ToU8Span(), 0, CreateFileOptions.None).ThrowIfFailure();
DirectorySaveDataFileSystem.CreateNew(out DirectorySaveDataFileSystem saveFs, baseFs, true, true)
.ThrowIfFailure();
Assert.Success(saveFs.GetEntryType(out _, "/file1".ToU8Span()));
Assert.Result(ResultFs.PathNotFound, saveFs.GetEntryType(out _, "/file2".ToU8Span()));
}
[Fact]
public void Initialize_InterruptedAfterCommitPart1_UsesWorkingData()
{
var baseFs = new InMemoryFileSystem();
baseFs.CreateDirectory("/_".ToU8Span()).ThrowIfFailure();
baseFs.CreateDirectory("/1".ToU8Span()).ThrowIfFailure();
// Set the existing files before initializing the save FS
baseFs.CreateFile("/_/file1".ToU8Span(), 0, CreateFileOptions.None).ThrowIfFailure();
baseFs.CreateFile("/1/file2".ToU8Span(), 0, CreateFileOptions.None).ThrowIfFailure();
DirectorySaveDataFileSystem.CreateNew(out DirectorySaveDataFileSystem saveFs, baseFs, true, true)
.ThrowIfFailure();
Assert.Result(ResultFs.PathNotFound, saveFs.GetEntryType(out _, "/file1".ToU8Span()));
Assert.Success(saveFs.GetEntryType(out _, "/file2".ToU8Span()));
}
[Fact]
public void Initialize_InterruptedDuringCommitPart2_UsesWorkingData()
{
var baseFs = new InMemoryFileSystem();
baseFs.CreateDirectory("/1".ToU8Span()).ThrowIfFailure();
// Set the existing files before initializing the save FS
baseFs.CreateFile("/1/file2".ToU8Span(), 0, CreateFileOptions.None).ThrowIfFailure();
DirectorySaveDataFileSystem.CreateNew(out DirectorySaveDataFileSystem saveFs, baseFs, true, true)
.ThrowIfFailure();
Assert.Result(ResultFs.PathNotFound, saveFs.GetEntryType(out _, "/file1".ToU8Span()));
Assert.Success(saveFs.GetEntryType(out _, "/file2".ToU8Span()));
}
}
}