Wabbajack.Test utils pass

This commit is contained in:
Timothy Baldridge
2020-03-26 15:15:44 -06:00
parent 07087ceef8
commit 1c9610dde1
9 changed files with 127 additions and 109 deletions

View File

@ -116,6 +116,12 @@ namespace Wabbajack.Common
await using var fs = File.Create(_path); await using var fs = File.Create(_path);
await fs.WriteAsync(Encoding.UTF8.GetBytes(text)); await fs.WriteAsync(Encoding.UTF8.GetBytes(text));
} }
public void WriteAllText(string text)
{
using var fs = File.Create(_path);
fs.Write(Encoding.UTF8.GetBytes(text));
}
public bool Exists => File.Exists(_path) || Directory.Exists(_path); public bool Exists => File.Exists(_path) || Directory.Exists(_path);
public bool IsFile => File.Exists(_path); public bool IsFile => File.Exists(_path);
@ -319,6 +325,11 @@ namespace Wabbajack.Common
{ {
await WriteAllTextAsync(string.Join("\n",strings)); await WriteAllTextAsync(string.Join("\n",strings));
} }
public void WriteAllLines(string[] strings)
{
WriteAllText(string.Join("\n",strings));
}
} }
public struct RelativePath : IPath, IEquatable<RelativePath> public struct RelativePath : IPath, IEquatable<RelativePath>

View File

@ -25,13 +25,13 @@ namespace Wabbajack.Lib
public abstract ModManager ModManager { get; } public abstract ModManager ModManager { get; }
public string ModListArchive { get; private set; } public AbsolutePath ModListArchive { get; private set; }
public ModList ModList { get; private set; } public ModList ModList { get; private set; }
public Dictionary<Hash, AbsolutePath> HashedArchives { get; set; } public Dictionary<Hash, AbsolutePath> HashedArchives { get; set; }
public SystemParameters SystemParameters { get; set; } public SystemParameters SystemParameters { get; set; }
public AInstaller(string archive, ModList modList, AbsolutePath outputFolder, AbsolutePath downloadFolder, SystemParameters parameters) public AInstaller(AbsolutePath archive, ModList modList, AbsolutePath outputFolder, AbsolutePath downloadFolder, SystemParameters parameters)
{ {
ModList = modList; ModList = modList;
ModListArchive = archive; ModListArchive = archive;
@ -58,7 +58,7 @@ namespace Wabbajack.Lib
public async Task<byte[]> LoadBytesFromPath(RelativePath path) public async Task<byte[]> LoadBytesFromPath(RelativePath path)
{ {
await using var fs = new FileStream(ModListArchive, FileMode.Open, FileAccess.Read, FileShare.Read); await using var fs = new FileStream((string)ModListArchive, FileMode.Open, FileAccess.Read, FileShare.Read);
using var ar = new ZipArchive(fs, ZipArchiveMode.Read); using var ar = new ZipArchive(fs, ZipArchiveMode.Read);
await using var ms = new MemoryStream(); await using var ms = new MemoryStream();
var entry = ar.GetEntry((string)path); var entry = ar.GetEntry((string)path);
@ -70,21 +70,19 @@ namespace Wabbajack.Lib
return ms.ToArray(); return ms.ToArray();
} }
public static ModList LoadFromFile(string path) public static ModList LoadFromFile(AbsolutePath path)
{ {
using (var fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read)) using var fs = new FileStream((string)path, FileMode.Open, FileAccess.Read, FileShare.Read);
using (var ar = new ZipArchive(fs, ZipArchiveMode.Read)) using var ar = new ZipArchive(fs, ZipArchiveMode.Read);
var entry = ar.GetEntry("modlist");
if (entry == null)
{ {
var entry = ar.GetEntry("modlist"); entry = ar.GetEntry("modlist.json");
if (entry == null)
{
entry = ar.GetEntry("modlist.json");
using (var e = entry.Open())
return e.FromJSON<ModList>();
}
using (var e = entry.Open()) using (var e = entry.Open())
return e.ReadAsMessagePack<ModList>(); return e.FromJSON<ModList>();
} }
using (var e = entry.Open())
return e.ReadAsMessagePack<ModList>();
} }
/// <summary> /// <summary>

View File

@ -32,7 +32,7 @@ namespace Wabbajack.Lib
public AbsolutePath? GameFolder { get; set; } public AbsolutePath? GameFolder { get; set; }
public MO2Installer(string archive, ModList modList, AbsolutePath outputFolder, AbsolutePath downloadFolder, SystemParameters parameters) public MO2Installer(AbsolutePath archive, ModList modList, AbsolutePath outputFolder, AbsolutePath downloadFolder, SystemParameters parameters)
: base( : base(
archive: archive, archive: archive,
modList: modList, modList: modList,

View File

@ -20,7 +20,7 @@ namespace Wabbajack.Lib
public override ModManager ModManager => ModManager.Vortex; public override ModManager ModManager => ModManager.Vortex;
public VortexInstaller(string archive, ModList modList, AbsolutePath outputFolder, AbsolutePath downloadFolder, SystemParameters parameters) public VortexInstaller(AbsolutePath archive, ModList modList, AbsolutePath outputFolder, AbsolutePath downloadFolder, SystemParameters parameters)
: base( : base(
archive: archive, archive: archive,
modList: modList, modList: modList,

View File

@ -1,19 +1,19 @@
using System; using System;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Wabbajack.Common; using Wabbajack.Common;
using Wabbajack.Lib; using Wabbajack.Lib;
using Wabbajack.Lib.LibCefHelpers; using Wabbajack.Lib.LibCefHelpers;
using Xunit;
using Xunit.Abstractions;
namespace Wabbajack.Test namespace Wabbajack.Test
{ {
public abstract class ACompilerTest public abstract class ACompilerTest : IDisposable
{ {
public TestContext TestContext { get; set; } public ITestOutputHelper TestContext { get; set; }
protected TestUtils utils { get; set; } protected TestUtils utils { get; set; }
[TestInitialize] public ACompilerTest()
public async Task TestInitialize()
{ {
Helpers.Init(); Helpers.Init();
Consts.TestMode = true; Consts.TestMode = true;
@ -25,8 +25,7 @@ namespace Wabbajack.Test
} }
[TestCleanup] public void Dispose()
public void TestCleanup()
{ {
utils.Dispose(); utils.Dispose();
} }
@ -36,8 +35,8 @@ namespace Wabbajack.Test
var compiler = new MO2Compiler( var compiler = new MO2Compiler(
mo2Folder: utils.MO2Folder, mo2Folder: utils.MO2Folder,
mo2Profile: profile, mo2Profile: profile,
outputFile: profile + Consts.ModListExtension); outputFile: OutputFile(profile));
Assert.IsTrue(await compiler.Begin()); Assert.True(await compiler.Begin());
return compiler; return compiler;
} }
@ -48,6 +47,11 @@ namespace Wabbajack.Test
return compiler.ModList; return compiler.ModList;
} }
private static AbsolutePath OutputFile(string profile)
{
return ((RelativePath)profile).RelativeToEntryPoint().WithExtension(Consts.ModListExtension);
}
protected async Task Install(MO2Compiler compiler) protected async Task Install(MO2Compiler compiler)
{ {
var modlist = AInstaller.LoadFromFile(compiler.ModListOutputFile); var modlist = AInstaller.LoadFromFile(compiler.ModListOutputFile);
@ -56,10 +60,22 @@ namespace Wabbajack.Test
modList: modlist, modList: modlist,
outputFolder: utils.InstallFolder, outputFolder: utils.InstallFolder,
downloadFolder: utils.DownloadsFolder, downloadFolder: utils.DownloadsFolder,
parameters: SystemParametersConstructor.Create()); parameters: CreateDummySystemParameters());
installer.WarnOnOverwrite = false; installer.WarnOnOverwrite = false;
installer.GameFolder = utils.GameFolder; installer.GameFolder = utils.GameFolder;
await installer.Begin(); await installer.Begin();
} }
private SystemParameters CreateDummySystemParameters()
{
return new SystemParameters
{
WindowsVersion = new Version("6.2.4.0"),
ScreenWidth = 1920,
ScreenHeight = 1080,
SystemMemorySize = 16 * 1024 * 1040,
VideoMemorySize = 4 * 1024 * 1024
};
}
} }
} }

View File

@ -1,32 +1,31 @@
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Wabbajack.Lib; using Wabbajack.Lib;
using Wabbajack.Lib.Downloaders; using Wabbajack.Lib.Downloaders;
using Wabbajack.Lib.ModListRegistry; using Wabbajack.Lib.ModListRegistry;
using Xunit;
namespace Wabbajack.Test namespace Wabbajack.Test
{ {
[TestClass]
public class ModlistMetadataTests public class ModlistMetadataTests
{ {
[TestMethod] [Fact]
public async Task TestLoadingModlists() public async Task TestLoadingModlists()
{ {
var modlists = await ModlistMetadata.LoadFromGithub(); var modlists = await ModlistMetadata.LoadFromGithub();
Assert.IsTrue(modlists.Count > 0); Assert.True(modlists.Count > 0);
} }
[TestMethod] [Fact]
public async Task VerifyLogoURLs() public async Task VerifyLogoURLs()
{ {
var modlists = await ModlistMetadata.LoadFromGithub(); var modlists = await ModlistMetadata.LoadFromGithub();
foreach (var modlist in modlists.Select(m => m.Links)) foreach (var modlist in modlists.Select(m => m.Links))
{ {
var logo_state = DownloadDispatcher.ResolveArchive(modlist.ImageUri); var logoState = DownloadDispatcher.ResolveArchive(modlist.ImageUri);
Assert.IsNotNull(logo_state); Assert.NotNull(logoState);
Assert.IsTrue(await logo_state.Verify(new Archive{Size = 0}), $"{modlist.ImageUri} is not valid"); Assert.True(await logoState.Verify(new Archive{Size = 0}), $"{modlist.ImageUri} is not valid");
} }
} }
} }

View File

@ -5,8 +5,8 @@ using System.IO.Compression;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Alphaleonis.Win32.Filesystem; using Alphaleonis.Win32.Filesystem;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Wabbajack.Common; using Wabbajack.Common;
using Xunit;
using Directory = Alphaleonis.Win32.Filesystem.Directory; using Directory = Alphaleonis.Win32.Filesystem.Directory;
using File = Alphaleonis.Win32.Filesystem.File; using File = Alphaleonis.Win32.Filesystem.File;
using FileInfo = Alphaleonis.Win32.Filesystem.FileInfo; using FileInfo = Alphaleonis.Win32.Filesystem.FileInfo;
@ -20,7 +20,7 @@ namespace Wabbajack.Test
public TestUtils() public TestUtils()
{ {
ID = RandomName(); ID = RandomName();
WorkingDirectory = Path.Combine(Directory.GetCurrentDirectory(), "tmp_data"); WorkingDirectory = ((RelativePath)"tmp_data").RelativeToEntryPoint();
} }
public AbsolutePath WorkingDirectory { get;} public AbsolutePath WorkingDirectory { get;}
@ -57,7 +57,7 @@ namespace Wabbajack.Test
Profiles.Do(profile => Profiles.Do(profile =>
{ {
File.WriteAllLines(Path.Combine(MO2Folder, "profiles", profile, "modlist.txt"), MO2Folder.Combine("profiles", profile, "modlist.txt").WriteAllLines(
Mods.Select(s => $"+{s}").ToArray()); Mods.Select(s => $"+{s}").ToArray());
}); });
} }
@ -65,7 +65,7 @@ namespace Wabbajack.Test
public string AddProfile(string name = null) public string AddProfile(string name = null)
{ {
string profile_name = name ?? RandomName(); string profile_name = name ?? RandomName();
Directory.CreateDirectory(Path.Combine(MO2Folder, "profiles", profile_name)); MO2Folder.Combine("profiles", profile_name).CreateDirectory();
Profiles.Add(profile_name); Profiles.Add(profile_name);
return profile_name; return profile_name;
} }
@ -75,9 +75,9 @@ namespace Wabbajack.Test
lock (this) lock (this)
{ {
string mod_name = name ?? RandomName(); string mod_name = name ?? RandomName();
var mod_folder = Path.Combine(MO2Folder, Consts.MO2ModFolderName, mod_name); var mod_folder = MO2Folder.Combine(Consts.MO2ModFolderName, (RelativePath)mod_name);
Directory.CreateDirectory(mod_folder); mod_folder.CreateDirectory();
File.WriteAllText(Path.Combine(mod_folder, "meta.ini"), "[General]"); mod_folder.Combine("meta.ini").WriteAllText("[General]");
Mods.Add(mod_name); Mods.Add(mod_name);
return mod_name; return mod_name;
} }
@ -91,18 +91,17 @@ namespace Wabbajack.Test
/// <param name="path"></param> /// <param name="path"></param>
/// <param name="random_fill"></param> /// <param name="random_fill"></param>
/// <returns></returns> /// <returns></returns>
public string AddModFile(string mod_name, string path, int random_fill=128) public AbsolutePath AddModFile(string mod_name, string path, int random_fill=128)
{ {
var full_path = Path.Combine(ModsFolder, mod_name, path); var full_path = ModsFolder.Combine(mod_name, path);
Directory.CreateDirectory(Path.GetDirectoryName(full_path)); full_path.Parent.CreateDirectory();
GenerateRandomFileData(full_path, random_fill); GenerateRandomFileData(full_path, random_fill);
return full_path; return full_path;
} }
public void GenerateRandomFileData(string full_path, int random_fill) public void GenerateRandomFileData(AbsolutePath full_path, int random_fill)
{ {
byte[] bytes = new byte[0]; byte[] bytes = new byte[0];
if (random_fill != 0) if (random_fill != 0)
@ -110,8 +109,7 @@ namespace Wabbajack.Test
bytes = new byte[random_fill]; bytes = new byte[random_fill];
RNG.NextBytes(bytes); RNG.NextBytes(bytes);
} }
full_path.WriteAllBytes(bytes);
File.WriteAllBytes(full_path, bytes);
} }
public static byte[] RandomData(int? size = null, int maxSize = 1024) public static byte[] RandomData(int? size = null, int maxSize = 1024)
@ -126,7 +124,7 @@ namespace Wabbajack.Test
public void Dispose() public void Dispose()
{ {
var exts = new [] {".md", ".exe"}; var exts = new [] {".md", ".exe"};
Utils.DeleteDirectory(Path.Combine(WorkingDirectory, ID)); WorkingDirectory.Combine(ID).DeleteDirectory();
Profiles.Do(p => Profiles.Do(p =>
{ {
foreach (var ext in exts) { foreach (var ext in exts) {
@ -149,18 +147,16 @@ namespace Wabbajack.Test
{ {
var name = RandomName() + ".zip"; var name = RandomName() + ".zip";
using(FileStream fs = new FileStream(Path.Combine(DownloadsFolder, name), FileMode.Create)) using FileStream fs = DownloadsFolder.Combine(name).Create();
using (ZipArchive archive = new ZipArchive(fs, ZipArchiveMode.Create)) using ZipArchive archive = new ZipArchive(fs, ZipArchiveMode.Create);
contents.Do(kv =>
{ {
contents.Do(kv => var entry = archive.CreateEntry(kv.Key);
{ using (var os = entry.Open())
var entry = archive.CreateEntry(kv.Key); os.Write(kv.Value, 0, kv.Value.Length);
using (var os = entry.Open()) });
os.Write(kv.Value, 0, kv.Value.Length);
});
}
File.WriteAllLines(Path.Combine(DownloadsFolder, name + Consts.MetaFileExtension), DownloadsFolder.Combine(name + Consts.MetaFileExtension).WriteAllLines(
new string[] new string[]
{ {
@ -173,92 +169,87 @@ namespace Wabbajack.Test
public void VerifyInstalledFile(string mod, string file) public void VerifyInstalledFile(string mod, string file)
{ {
var src = Path.Combine(MO2Folder, Consts.MO2ModFolderName, mod, file); var src = MO2Folder.Combine((string)Consts.MO2ModFolderName, mod, file);
Assert.IsTrue(File.Exists(src), src); Assert.True(src.Exists);
var dest = Path.Combine(InstallFolder, Consts.MO2ModFolderName, mod, file); var dest = InstallFolder.Combine((string)Consts.MO2ModFolderName, mod, file);
Assert.IsTrue(File.Exists(dest), dest); Assert.True(src.Exists);
var src_data = File.ReadAllBytes(src); var srcData = src.ReadAllBytes();
var dest_data = File.ReadAllBytes(dest); var destData = dest.ReadAllBytes();
Assert.AreEqual(src_data.Length, dest_data.Length); Assert.Equal(srcData.Length, destData.Length);
for(int x = 0; x < src_data.Length; x++) for(int x = 0; x < srcData.Length; x++)
{ {
if (src_data[x] != dest_data[x]) if (srcData[x] != destData[x])
Assert.Fail($"Index {x} of {mod}\\{file} are not the same"); Assert.True(false, $"Index {x} of {mod}\\{file} are not the same");
} }
} }
public void VerifyInstalledGameFile(string file) public void VerifyInstalledGameFile(string file)
{ {
var src = Path.Combine(GameFolder, file); var src = GameFolder.Combine(file);
Assert.IsTrue(File.Exists(src), src); Assert.True(src.Exists);
var dest = Path.Combine(InstallFolder, Consts.GameFolderFilesDir, file); var dest = InstallFolder.Combine((string)Consts.GameFolderFilesDir, file);
Assert.IsTrue(File.Exists(dest), dest); Assert.True(dest.Exists);
var src_data = File.ReadAllBytes(src); var srcData = src.ReadAllBytes();
var dest_data = File.ReadAllBytes(dest); var destData = dest.ReadAllBytes();
Assert.AreEqual(src_data.Length, dest_data.Length); Assert.Equal(srcData.Length, destData.Length);
for(int x = 0; x < src_data.Length; x++) for(int x = 0; x < srcData.Length; x++)
{ {
if (src_data[x] != dest_data[x]) if (srcData[x] != destData[x])
Assert.Fail($"Index {x} of {Consts.GameFolderFilesDir}\\{file} are not the same"); Assert.True(false, $"Index {x} of {Consts.GameFolderFilesDir}\\{file} are not the same");
} }
} }
public string PathOfInstalledFile(string mod, string file) public AbsolutePath PathOfInstalledFile(string mod, string file)
{ {
return Path.Combine(InstallFolder, Consts.MO2ModFolderName, mod, file); return InstallFolder.Combine((string)Consts.MO2ModFolderName, mod, file);
} }
public void VerifyAllFiles() public void VerifyAllFiles()
{ {
var skip_files = new HashSet<string> {"portable.txt"}; var skipFiles = new []{"portable.txt"}.Select(e => (RelativePath)e).ToHashSet();
foreach (var dest_file in Directory.EnumerateFiles(InstallFolder, "*", DirectoryEnumerationOptions.Recursive)) foreach (var destFile in InstallFolder.EnumerateFiles())
{ {
var rel_file = dest_file.RelativeTo(InstallFolder); var relFile = destFile.RelativeTo(InstallFolder);
if (rel_file.StartsWith(Consts.LOOTFolderFilesDir) || rel_file.StartsWith(Consts.GameFolderFilesDir)) if (destFile.InFolder(Consts.LOOTFolderFilesDir.RelativeTo(MO2Folder)) || destFile.InFolder(Consts.GameFolderFilesDir.RelativeTo(MO2Folder)))
continue; continue;
if (!skip_files.Contains(rel_file)) if (!skipFiles.Contains(relFile))
Assert.IsTrue(File.Exists(Path.Combine(MO2Folder, rel_file)), $"Only in Destination: {rel_file}"); Assert.True(MO2Folder.Combine(relFile).Exists, $"Only in Destination: {relFile}");
} }
var skip_extensions = new HashSet<string> {".txt", ".ini"}; var skipExtensions = new []{".txt", ".ini"}.Select(e => new Extension(e)).ToHashSet();
foreach (var src_file in Directory.EnumerateFiles(MO2Folder, "*", DirectoryEnumerationOptions.Recursive)) foreach (var srcFile in MO2Folder.EnumerateFiles())
{ {
var rel_file = src_file.RelativeTo(MO2Folder); var relFile = srcFile.RelativeTo(MO2Folder);
if (rel_file.StartsWith("downloads\\")) if (relFile.StartsWith("downloads\\"))
continue; continue;
var dest_file = Path.Combine(InstallFolder, rel_file); var destFile = InstallFolder.Combine(relFile);
Assert.IsTrue(File.Exists(dest_file), $"Only in Source: {rel_file}"); Assert.True(destFile.Exists, $"Only in Source: {relFile}");
var fi_src = new FileInfo(src_file); if (!skipExtensions.Contains(srcFile.Extension))
var fi_dest = new FileInfo(dest_file);
if (!skip_extensions.Contains(Path.GetExtension(src_file)))
{ {
Assert.AreEqual(fi_src.Length, fi_dest.Length, $"Differing sizes {rel_file}"); Assert.Equal(srcFile.Size, destFile.Size);
Assert.AreEqual(src_file.FileHash(), dest_file.FileHash(), $"Differing content hash {rel_file}"); Assert.Equal(srcFile.FileHash(), destFile.FileHash());
} }
} }
} }
public string AddGameFile(string path, int i) public AbsolutePath AddGameFile(string path, int i)
{ {
var full_path = Path.Combine(GameFolder, path); var fullPath = GameFolder.Combine(path);
var dir = Path.GetDirectoryName(full_path); fullPath.Parent.CreateDirectory();
if (!Directory.Exists(dir)) GenerateRandomFileData(fullPath, i);
Directory.CreateDirectory(dir); return fullPath;
GenerateRandomFileData(full_path, i);
return full_path;
} }

View File

@ -47,9 +47,9 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="CefSharp.Common" Version="79.1.350" /> <PackageReference Include="CefSharp.Common" Version="79.1.350" />
<PackageReference Include="CefSharp.OffScreen" Version="79.1.350" /> <PackageReference Include="CefSharp.OffScreen" Version="79.1.350" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.4.0" /> <PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="MSTest.TestAdapter" Version="2.1.0" /> <PackageReference Include="xunit.runner.console" Version="2.4.1" />
<PackageReference Include="MSTest.TestFramework" Version="2.1.0" /> <PackageReference Include="xunit.runner.visualstudio" Version="2.4.1" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@ -5,6 +5,8 @@ using System.Data;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows; using System.Windows;
using System.Windows.Interop;
using System.Windows.Media;
using Wabbajack.Common; using Wabbajack.Common;
using Wabbajack.Util; using Wabbajack.Util;
@ -17,6 +19,7 @@ namespace Wabbajack
{ {
public App() public App()
{ {
RenderOptions.ProcessRenderMode = RenderMode.SoftwareOnly;
CLIOld.ParseOptions(Environment.GetCommandLineArgs()); CLIOld.ParseOptions(Environment.GetCommandLineArgs());
if (CLIArguments.Help) if (CLIArguments.Help)
CLIOld.DisplayHelpText(); CLIOld.DisplayHelpText();