wabbajack/Wabbajack.Compiler.Test/SanityTests.cs

226 lines
7.7 KiB
C#
Raw Permalink Normal View History

2021-09-27 12:42:46 +00:00
using System;
using System.IO;
2021-10-23 16:51:17 +00:00
using System.Linq;
using System.Threading;
2021-09-27 12:42:46 +00:00
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Wabbajack.Common;
using Wabbajack.Compression.BSA;
using Wabbajack.DTOs;
using Wabbajack.DTOs.Directives;
using Wabbajack.DTOs.Texture;
using Wabbajack.Hashing.PHash;
using Wabbajack.Paths.IO;
2021-10-21 03:18:15 +00:00
using Wabbajack.RateLimiter;
2021-09-27 12:42:46 +00:00
using Xunit;
2021-10-23 16:51:17 +00:00
namespace Wabbajack.Compiler.Test;
public class CompilerSanityTests : IAsyncLifetime
2021-09-27 12:42:46 +00:00
{
2021-10-23 16:51:17 +00:00
private readonly FileExtractor.FileExtractor _fileExtractor;
private readonly ModListHarness _harness;
private readonly ILogger<CompilerSanityTests> _logger;
private readonly TemporaryFileManager _manager;
private readonly ParallelOptions _parallelOptions;
private readonly IServiceScope _scope;
private readonly IServiceProvider _serviceProvider;
private Mod _mod;
private ModList? _modlist;
private readonly IImageLoader _imageLoader;
2021-10-23 16:51:17 +00:00
public CompilerSanityTests(ILogger<CompilerSanityTests> logger, IServiceProvider serviceProvider,
FileExtractor.FileExtractor fileExtractor,
TemporaryFileManager manager,
ParallelOptions parallelOptions,
IImageLoader imageLoader)
2021-09-27 12:42:46 +00:00
{
2021-10-23 16:51:17 +00:00
_logger = logger;
_serviceProvider = serviceProvider;
_scope = _serviceProvider.CreateScope();
_harness = _scope.ServiceProvider.GetService<ModListHarness>()!;
_fileExtractor = fileExtractor;
_manager = manager;
_parallelOptions = parallelOptions;
_imageLoader = imageLoader;
2021-10-23 16:51:17 +00:00
}
2021-09-27 12:42:46 +00:00
2021-10-23 16:51:17 +00:00
public async Task InitializeAsync()
{
_mod = await _harness.InstallMod(Ext.Zip,
new Uri(
"https://authored-files.wabbajack.org/Tonal%20Architect_WJ_TEST_FILES.zip_9cb97a01-3354-4077-9e4a-7e808d47794f"));
}
2021-09-27 12:42:46 +00:00
2022-10-08 03:43:44 +00:00
public Task DisposeAsync()
2021-10-23 16:51:17 +00:00
{
2022-10-08 03:43:44 +00:00
return Task.CompletedTask;
2021-10-23 16:51:17 +00:00
}
2022-05-27 05:41:11 +00:00
private async Task CompileAndValidate(int expectedDirectives, Action<CompilerSettings>? configureSettings = null)
2021-10-23 16:51:17 +00:00
{
_modlist = await _harness.Compile(configureSettings);
Assert.NotNull(_modlist);
Assert.Single(_modlist!.Archives);
Assert.NotEmpty(_modlist.Directives.Select(d => d.To).ToHashSet());
Assert.Equal(expectedDirectives, _modlist.Directives.Length);
}
private async Task InstallAndValidate()
{
await _harness.Install();
foreach (var file in _mod.FullPath.EnumerateFiles())
_harness.VerifyInstalledFile(file);
}
2021-09-27 12:42:46 +00:00
2021-10-23 16:51:17 +00:00
[Fact]
public async Task CanCompileDirectMatchFiles()
{
await CompileAndValidate(4);
foreach (var directive in _modlist!.Directives.OfType<FromArchive>())
Assert.Equal(_modlist.Archives.First().Hash, directive.ArchiveHashPath.Hash);
await InstallAndValidate();
}
[Fact]
public async Task CanPatchFiles()
{
foreach (var file in _mod.FullPath.EnumerateFiles(Ext.Esp))
2021-09-27 12:42:46 +00:00
{
2021-10-23 16:51:17 +00:00
await using var fs = file.Open(FileMode.Open, FileAccess.Write);
fs.Position = 42;
fs.WriteByte(42);
2021-09-27 12:42:46 +00:00
}
2021-10-23 16:51:17 +00:00
await CompileAndValidate(4);
2022-10-08 03:43:44 +00:00
Assert.Single(_modlist!.Directives.OfType<PatchedFromArchive>());
2021-10-23 16:51:17 +00:00
await InstallAndValidate();
}
[Fact]
public async Task CanExtractBSAs()
{
2021-10-25 21:06:40 +00:00
var bsa = _mod.FullPath.EnumerateFiles(Ext.Bsa)
.OrderBy(d => d.Size())
.First();
2021-10-23 16:51:17 +00:00
await _fileExtractor.ExtractAll(bsa, _mod.FullPath, CancellationToken.None);
bsa.Delete();
await CompileAndValidate(39);
await InstallAndValidate();
}
[Fact]
public async Task CanRecreateBSAs()
{
var bsa = _mod.FullPath.EnumerateFiles(Ext.Bsa).MinBy(d => d.Size());
2021-10-23 16:51:17 +00:00
await _fileExtractor.ExtractAll(bsa, _mod.FullPath, CancellationToken.None);
var reader = await BSADispatch.Open(bsa);
var bsaState = reader.State;
var fileStates = reader.Files.Select(f => f.State).ToArray();
bsa.Delete();
await using var creator = BSADispatch.CreateBuilder(bsaState, _manager);
2021-10-23 16:51:17 +00:00
await fileStates.Take(2).PDoAll(new Resource<CompilerSanityTests>(),
async f => await creator.AddFile(f, f.Path.RelativeTo(_mod.FullPath).Open(FileMode.Open),
CancellationToken.None));
2021-09-27 12:42:46 +00:00
{
2021-10-23 16:51:17 +00:00
await using var fs = bsa.Open(FileMode.Create, FileAccess.Write);
await creator.Build(fs, CancellationToken.None);
2021-09-27 12:42:46 +00:00
}
2021-10-23 16:51:17 +00:00
await CompileAndValidate(42);
2022-10-08 03:43:44 +00:00
Assert.Single(_modlist!.Directives.OfType<CreateBSA>());
2021-10-23 16:51:17 +00:00
await InstallAndValidate();
}
[Fact]
public async Task DuplicateFilesAreCopied()
{
foreach (var file in _mod.FullPath.EnumerateFiles(Ext.Esp))
2021-09-27 12:42:46 +00:00
{
2021-10-23 16:51:17 +00:00
var newPath = file.RelativeTo(_mod.FullPath).RelativeTo(_mod.FullPath.Combine("duplicates"));
newPath.Parent.CreateDirectory();
2022-10-07 21:02:16 +00:00
await file.CopyToAsync(newPath, CancellationToken.None);
2021-09-27 12:42:46 +00:00
}
2021-10-23 16:51:17 +00:00
await CompileAndValidate(5);
2021-09-27 12:42:46 +00:00
2021-10-23 16:51:17 +00:00
foreach (var directive in _modlist!.Directives.OfType<FromArchive>())
Assert.Equal(_modlist.Archives.First().Hash, directive.ArchiveHashPath.Hash);
2021-09-27 12:42:46 +00:00
2021-10-23 16:51:17 +00:00
await InstallAndValidate();
}
[Fact]
public async Task NoMatchIncludeIncludesNonMatchingFiles()
{
var someFile = _mod.FullPath.Combine("some folder", "some file.pex");
someFile.Parent.CreateDirectory();
await someFile.WriteAllTextAsync("Cheese for Everyone!");
var someFile2 = _mod.FullPath.Combine("some folder2", "some other folder", "some file.pex");
someFile2.Parent.CreateDirectory();
await someFile2.WriteAllTextAsync("More Cheese for Everyone!");
await CompileAndValidate(6, settings =>
2021-09-27 12:42:46 +00:00
{
2021-10-23 16:51:17 +00:00
settings.NoMatchInclude = new[]
2021-09-27 12:42:46 +00:00
{
2021-10-23 16:51:17 +00:00
someFile.RelativeTo(_harness._source),
someFile2.RelativeTo(_harness._source)
};
});
2021-09-27 12:42:46 +00:00
2021-10-23 16:51:17 +00:00
Assert.Equal(3, _modlist!.Directives.OfType<InlineFile>().Count());
2021-09-27 12:42:46 +00:00
2021-10-23 16:51:17 +00:00
await InstallAndValidate();
}
[Fact]
public async Task CanDetectSimilarUnpackedTextures()
{
foreach (var bsa in _mod.FullPath.EnumerateFiles(Ext.Bsa))
2021-09-27 12:42:46 +00:00
{
2021-10-23 16:51:17 +00:00
await _fileExtractor.ExtractAll(bsa, _mod.FullPath, CancellationToken.None, p => p.Extension == Ext.Dds);
bsa.Delete();
2021-09-27 12:42:46 +00:00
}
2021-10-23 16:51:17 +00:00
foreach (var file in _mod.FullPath.EnumerateFiles()
.Where(p => p.Extension != Ext.Dds || !p.FileName.FileNameStartsWith("mrkinn"))) file.Delete();
2021-09-27 12:42:46 +00:00
2021-10-23 16:51:17 +00:00
foreach (var file in _mod.FullPath.EnumerateFiles())
2021-09-27 12:42:46 +00:00
{
var oldState = await _imageLoader.Load(file);
2021-10-23 16:51:17 +00:00
Assert.NotEqual(DXGI_FORMAT.UNKNOWN, oldState.Format);
_logger.LogInformation("Recompressing {file}", file.FileName);
await _imageLoader.Recompress(file, 512, 512, 1, DXGI_FORMAT.BC7_UNORM, file, CancellationToken.None);
2021-09-27 12:42:46 +00:00
var state = await _imageLoader.Load(file);
2021-10-23 16:51:17 +00:00
Assert.Equal(DXGI_FORMAT.BC7_UNORM, state.Format);
}
2021-09-27 12:42:46 +00:00
2021-10-23 16:51:17 +00:00
await CompileAndValidate(3);
2021-09-27 12:42:46 +00:00
2021-10-23 16:51:17 +00:00
Assert.Equal(2, _modlist!.Directives.OfType<TransformedTexture>().Count());
2021-09-27 12:42:46 +00:00
2021-10-23 16:51:17 +00:00
foreach (var directive in _modlist!.Directives.OfType<TransformedTexture>())
{
_logger.LogInformation("For file {name} {format}", directive.To.FileName, directive.ImageState.Format);
Assert.Equal(directive.To.FileName, directive.ArchiveHashPath.Parts[^1].FileName);
Assert.Equal(512, directive.ImageState.Height);
Assert.Equal(512, directive.ImageState.Width);
Assert.Equal(DXGI_FORMAT.BC7_UNORM, directive.ImageState.Format);
2021-09-27 12:42:46 +00:00
}
2021-10-23 16:51:17 +00:00
await InstallAndValidate();
2021-09-27 12:42:46 +00:00
}
}