2019-11-14 22:22:53 +00:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.IO.Compression;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
using Alphaleonis.Win32.Filesystem;
|
|
|
|
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
|
|
|
|
using Wabbajack.Common;
|
|
|
|
|
|
|
|
|
|
namespace Wabbajack.VirtualFileSystem.Test
|
|
|
|
|
{
|
|
|
|
|
[TestClass]
|
|
|
|
|
public class VFSTests
|
|
|
|
|
{
|
2020-03-24 02:46:30 +00:00
|
|
|
|
private static readonly AbsolutePath VFS_TEST_DIR = "vfs_test_dir".ToPath().RelativeToEntryPoint();
|
|
|
|
|
private static readonly AbsolutePath TEST_ZIP = "test.zip".RelativeTo(VFS_TEST_DIR);
|
|
|
|
|
private static readonly AbsolutePath TEST_TXT = "test.txt".RelativeTo(VFS_TEST_DIR);
|
|
|
|
|
private static readonly AbsolutePath ARCHIVE_TEST_TXT = "archive/text.txt".RelativeTo(VFS_TEST_DIR);
|
2019-11-14 22:22:53 +00:00
|
|
|
|
private Context context;
|
|
|
|
|
|
|
|
|
|
public TestContext TestContext { get; set; }
|
2019-11-17 04:16:42 +00:00
|
|
|
|
public WorkQueue Queue { get; set; }
|
2019-11-14 22:22:53 +00:00
|
|
|
|
|
|
|
|
|
[TestInitialize]
|
|
|
|
|
public void Setup()
|
|
|
|
|
{
|
2019-12-04 04:12:08 +00:00
|
|
|
|
Utils.LogMessages.Subscribe(f => TestContext.WriteLine(f.ShortDescription));
|
2020-03-23 23:03:26 +00:00
|
|
|
|
VFS_TEST_DIR.DeleteDirectory();
|
|
|
|
|
VFS_TEST_DIR.CreateDirectory();
|
2019-11-17 04:16:42 +00:00
|
|
|
|
Queue = new WorkQueue();
|
|
|
|
|
context = new Context(Queue);
|
2019-11-14 22:22:53 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[TestMethod]
|
2019-12-04 01:26:26 +00:00
|
|
|
|
public async Task FilesAreIndexed()
|
2019-11-14 22:22:53 +00:00
|
|
|
|
{
|
2020-03-24 02:46:30 +00:00
|
|
|
|
await AddFile(TEST_TXT, "This is a test");
|
2019-12-04 01:26:26 +00:00
|
|
|
|
await AddTestRoot();
|
2019-11-14 22:22:53 +00:00
|
|
|
|
|
2020-03-23 23:03:26 +00:00
|
|
|
|
var file = context.Index.ByRootPath["test.txt".ToPath().RelativeTo(VFS_TEST_DIR)];
|
2019-11-14 22:22:53 +00:00
|
|
|
|
Assert.IsNotNull(file);
|
|
|
|
|
|
|
|
|
|
Assert.AreEqual(file.Size, 14);
|
|
|
|
|
Assert.AreEqual(file.Hash, "qX0GZvIaTKM=");
|
|
|
|
|
}
|
|
|
|
|
|
2019-12-04 01:26:26 +00:00
|
|
|
|
private async Task AddTestRoot()
|
2019-11-14 22:22:53 +00:00
|
|
|
|
{
|
2020-03-23 23:03:26 +00:00
|
|
|
|
await context.AddRoot(VFS_TEST_DIR);
|
|
|
|
|
await context.WriteToFile("vfs_cache.bin".RelativeTo(VFS_TEST_DIR));
|
|
|
|
|
await context.IntegrateFromFile( "vfs_cache.bin".RelativeTo(VFS_TEST_DIR));
|
2019-11-14 22:22:53 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[TestMethod]
|
|
|
|
|
public async Task ArchiveContentsAreIndexed()
|
|
|
|
|
{
|
2020-03-24 02:46:30 +00:00
|
|
|
|
await AddFile(ARCHIVE_TEST_TXT, "This is a test");
|
|
|
|
|
ZipUpFolder(ARCHIVE_TEST_TXT.Parent, TEST_ZIP);
|
2019-12-04 01:26:26 +00:00
|
|
|
|
await AddTestRoot();
|
2019-11-14 22:22:53 +00:00
|
|
|
|
|
2020-03-24 02:46:30 +00:00
|
|
|
|
var absPath = "test.zip".RelativeTo(VFS_TEST_DIR);
|
|
|
|
|
var file = context.Index.ByRootPath[absPath];
|
2019-11-14 22:22:53 +00:00
|
|
|
|
Assert.IsNotNull(file);
|
|
|
|
|
|
|
|
|
|
Assert.AreEqual(128, file.Size);
|
2020-03-24 02:46:30 +00:00
|
|
|
|
Assert.AreEqual(absPath.FileHash(), file.Hash);
|
2019-11-14 22:22:53 +00:00
|
|
|
|
|
|
|
|
|
Assert.IsTrue(file.IsArchive);
|
2020-03-23 23:03:26 +00:00
|
|
|
|
var innerFile = file.Children.First();
|
|
|
|
|
Assert.AreEqual(14, innerFile.Size);
|
|
|
|
|
Assert.AreEqual("qX0GZvIaTKM=", innerFile.Hash);
|
2019-11-14 22:22:53 +00:00
|
|
|
|
Assert.AreSame(file, file.Children.First().Parent);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[TestMethod]
|
|
|
|
|
public async Task DuplicateFileHashes()
|
|
|
|
|
{
|
2020-03-24 02:46:30 +00:00
|
|
|
|
await AddFile(ARCHIVE_TEST_TXT, "This is a test");
|
|
|
|
|
ZipUpFolder(ARCHIVE_TEST_TXT.Parent, TEST_ZIP);
|
2019-11-14 22:22:53 +00:00
|
|
|
|
|
2020-03-24 02:46:30 +00:00
|
|
|
|
await AddFile(TEST_TXT, "This is a test");
|
2019-12-04 01:26:26 +00:00
|
|
|
|
await AddTestRoot();
|
2019-11-14 22:22:53 +00:00
|
|
|
|
|
|
|
|
|
|
2020-03-22 15:50:53 +00:00
|
|
|
|
var files = context.Index.ByHash[Hash.FromBase64("qX0GZvIaTKM=")];
|
2019-11-14 22:22:53 +00:00
|
|
|
|
Assert.AreEqual(files.Count(), 2);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[TestMethod]
|
|
|
|
|
public async Task DeletedFilesAreRemoved()
|
|
|
|
|
{
|
2020-03-24 02:46:30 +00:00
|
|
|
|
await AddFile(TEST_TXT, "This is a test");
|
2019-12-04 01:26:26 +00:00
|
|
|
|
await AddTestRoot();
|
2019-11-14 22:22:53 +00:00
|
|
|
|
|
2020-03-24 02:46:30 +00:00
|
|
|
|
var file = context.Index.ByRootPath[TEST_TXT];
|
2019-11-14 22:22:53 +00:00
|
|
|
|
Assert.IsNotNull(file);
|
|
|
|
|
|
|
|
|
|
Assert.AreEqual(file.Size, 14);
|
|
|
|
|
Assert.AreEqual(file.Hash, "qX0GZvIaTKM=");
|
|
|
|
|
|
2020-03-24 02:46:30 +00:00
|
|
|
|
TEST_TXT.Delete();
|
2019-11-14 22:22:53 +00:00
|
|
|
|
|
2019-12-04 01:26:26 +00:00
|
|
|
|
await AddTestRoot();
|
2019-11-14 22:22:53 +00:00
|
|
|
|
|
2020-03-24 02:46:30 +00:00
|
|
|
|
CollectionAssert.DoesNotContain(context.Index.ByFullPath, TEST_TXT);
|
2019-11-14 22:22:53 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[TestMethod]
|
2019-12-04 01:26:26 +00:00
|
|
|
|
public async Task UnmodifiedFilesAreNotReIndexed()
|
2019-11-14 22:22:53 +00:00
|
|
|
|
{
|
2020-03-24 02:46:30 +00:00
|
|
|
|
await AddFile(TEST_TXT, "This is a test");
|
2019-12-04 01:26:26 +00:00
|
|
|
|
await AddTestRoot();
|
2019-11-14 22:22:53 +00:00
|
|
|
|
|
2020-03-24 02:46:30 +00:00
|
|
|
|
var old_file = context.Index.ByRootPath[TEST_TXT];
|
2019-11-14 22:22:53 +00:00
|
|
|
|
var old_time = old_file.LastAnalyzed;
|
|
|
|
|
|
2019-12-04 01:26:26 +00:00
|
|
|
|
await AddTestRoot();
|
2019-11-14 22:22:53 +00:00
|
|
|
|
|
2020-03-24 02:46:30 +00:00
|
|
|
|
var new_file = context.Index.ByRootPath[TEST_TXT];
|
2019-11-14 22:22:53 +00:00
|
|
|
|
|
|
|
|
|
Assert.AreEqual(old_time, new_file.LastAnalyzed);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[TestMethod]
|
2019-12-04 01:26:26 +00:00
|
|
|
|
public async Task CanStageSimpleArchives()
|
2019-11-14 22:22:53 +00:00
|
|
|
|
{
|
2020-03-24 02:46:30 +00:00
|
|
|
|
await AddFile(ARCHIVE_TEST_TXT, "This is a test");
|
|
|
|
|
ZipUpFolder(ARCHIVE_TEST_TXT.Parent, TEST_ZIP);
|
2019-12-04 01:26:26 +00:00
|
|
|
|
await AddTestRoot();
|
2019-11-14 22:22:53 +00:00
|
|
|
|
|
2020-03-24 02:46:30 +00:00
|
|
|
|
var file = context.Index.ByFullPath[new FullPath(TEST_ZIP, new []{(RelativePath)"test.txt"})];
|
2019-11-14 22:22:53 +00:00
|
|
|
|
|
2019-12-04 01:26:26 +00:00
|
|
|
|
var cleanup = await context.Stage(new List<VirtualFile> {file});
|
2020-03-24 02:46:30 +00:00
|
|
|
|
Assert.AreEqual("This is a test", await file.StagedPath.ReadAllTextAsync());
|
2019-11-14 22:22:53 +00:00
|
|
|
|
|
|
|
|
|
cleanup();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[TestMethod]
|
2019-12-04 01:26:26 +00:00
|
|
|
|
public async Task CanStageNestedArchives()
|
2019-11-14 22:22:53 +00:00
|
|
|
|
{
|
2020-03-24 02:46:30 +00:00
|
|
|
|
await AddFile(ARCHIVE_TEST_TXT, "This is a test");
|
|
|
|
|
ZipUpFolder(ARCHIVE_TEST_TXT.Parent, TEST_ZIP);
|
2019-11-14 22:22:53 +00:00
|
|
|
|
|
2020-03-24 02:46:30 +00:00
|
|
|
|
var inner_dir = @"archive\other\dir".RelativeTo(VFS_TEST_DIR);
|
|
|
|
|
inner_dir.CreateDirectory();
|
|
|
|
|
TEST_ZIP.MoveTo( @"archive\other\dir\nested.zip".RelativeTo(VFS_TEST_DIR));
|
|
|
|
|
ZipUpFolder(ARCHIVE_TEST_TXT.Parent, TEST_ZIP);
|
2019-11-14 22:22:53 +00:00
|
|
|
|
|
2019-12-04 01:26:26 +00:00
|
|
|
|
await AddTestRoot();
|
2019-11-14 22:22:53 +00:00
|
|
|
|
|
2020-03-22 15:50:53 +00:00
|
|
|
|
var files = context.Index.ByHash[Hash.FromBase64("qX0GZvIaTKM=")];
|
2019-11-14 22:22:53 +00:00
|
|
|
|
|
2019-12-04 01:26:26 +00:00
|
|
|
|
var cleanup = await context.Stage(files);
|
2019-11-14 22:22:53 +00:00
|
|
|
|
|
|
|
|
|
foreach (var file in files)
|
2020-03-24 02:46:30 +00:00
|
|
|
|
Assert.AreEqual("This is a test", await file.StagedPath.ReadAllTextAsync());
|
2019-11-14 22:22:53 +00:00
|
|
|
|
|
|
|
|
|
cleanup();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[TestMethod]
|
2019-12-04 01:26:26 +00:00
|
|
|
|
public async Task CanRequestPortableFileTrees()
|
2019-11-14 22:22:53 +00:00
|
|
|
|
{
|
2020-03-24 02:46:30 +00:00
|
|
|
|
await AddFile(ARCHIVE_TEST_TXT, "This is a test");
|
|
|
|
|
ZipUpFolder(ARCHIVE_TEST_TXT.Parent, TEST_ZIP);
|
2019-11-14 22:22:53 +00:00
|
|
|
|
|
2020-03-24 02:46:30 +00:00
|
|
|
|
@"archive\other\dir".RelativeTo(VFS_TEST_DIR).CreateDirectory();
|
|
|
|
|
TEST_ZIP.MoveTo(@"archive\other\dir\nested.zip".RelativeTo(VFS_TEST_DIR));
|
|
|
|
|
ZipUpFolder(ARCHIVE_TEST_TXT.Parent, TEST_ZIP);
|
2019-11-14 22:22:53 +00:00
|
|
|
|
|
2019-12-04 01:26:26 +00:00
|
|
|
|
await AddTestRoot();
|
2019-11-14 22:22:53 +00:00
|
|
|
|
|
2020-03-22 15:50:53 +00:00
|
|
|
|
var files = context.Index.ByHash[Hash.FromBase64("qX0GZvIaTKM=")];
|
2020-03-24 02:46:30 +00:00
|
|
|
|
var archive = context.Index.ByRootPath[TEST_ZIP];
|
2019-11-14 22:22:53 +00:00
|
|
|
|
|
|
|
|
|
var state = context.GetPortableState(files);
|
|
|
|
|
|
2020-03-24 02:58:39 +00:00
|
|
|
|
var newContext = new Context(Queue);
|
2019-11-14 22:22:53 +00:00
|
|
|
|
|
2020-03-24 02:58:39 +00:00
|
|
|
|
await newContext.IntegrateFromPortable(state,
|
2020-03-24 02:46:30 +00:00
|
|
|
|
new Dictionary<Hash, AbsolutePath> {{archive.Hash, archive.FullPath.Base}});
|
2019-11-14 22:22:53 +00:00
|
|
|
|
|
2020-03-24 02:58:39 +00:00
|
|
|
|
var newFiles = newContext.Index.ByHash[Hash.FromBase64("qX0GZvIaTKM=")];
|
2019-11-14 22:22:53 +00:00
|
|
|
|
|
2020-03-24 02:58:39 +00:00
|
|
|
|
var close = await newContext.Stage(newFiles);
|
2019-11-14 22:22:53 +00:00
|
|
|
|
|
2020-03-24 02:58:39 +00:00
|
|
|
|
foreach (var file in newFiles)
|
2020-03-24 02:46:30 +00:00
|
|
|
|
Assert.AreEqual("This is a test", await file.StagedPath.ReadAllTextAsync());
|
2019-11-14 22:22:53 +00:00
|
|
|
|
|
|
|
|
|
close();
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-24 02:46:30 +00:00
|
|
|
|
private static async Task AddFile(AbsolutePath filename, string text)
|
2019-11-14 22:22:53 +00:00
|
|
|
|
{
|
2020-03-24 02:46:30 +00:00
|
|
|
|
filename.Parent.CreateDirectory();
|
|
|
|
|
await filename.WriteAllTextAsync(text);
|
2019-11-14 22:22:53 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-03-24 02:46:30 +00:00
|
|
|
|
private static void ZipUpFolder(AbsolutePath folder, AbsolutePath output)
|
2019-11-14 22:22:53 +00:00
|
|
|
|
{
|
2020-03-24 02:46:30 +00:00
|
|
|
|
ZipFile.CreateFromDirectory((string)folder, (string)output);
|
|
|
|
|
folder.DeleteDirectory();
|
2019-11-14 22:22:53 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2019-11-23 17:37:24 +00:00
|
|
|
|
}
|