using System.Text; using XFEEDToolBox.NativeSupport; using XFEExtension.NetCore.XUnit.Attributes; namespace XFEEDToolBox.Test; [TestFixture] public class NativeSupportPackageTests { private static Dictionary Resources(string version = "one") => NativeSupportPackage.ResourcePaths.ToDictionary(path => path, path => Encoding.UTF8.GetBytes(version + ":" + path)); [Test] public void CompleteBundleExtractsNestedModulesAndReusesMatchingFiles() { using var temporary = new TemporaryDirectory(); var resources = Resources(); var directory = NativeSupportPackage.ExtractPackage(temporary.Path, resources); foreach (var pair in resources) Check.Equal(Encoding.UTF8.GetString(pair.Value), File.ReadAllText(Path.Combine(directory, pair.Key))); var module = Path.Combine(directory, "dinput8.dll"); File.SetLastWriteTimeUtc(module, new DateTime(2025, 1, 1, 0, 0, 0, DateTimeKind.Utc)); var before = File.GetLastWriteTimeUtc(module); Check.Equal(directory, NativeSupportPackage.ExtractPackage(temporary.Path, resources)); Check.Equal(before, File.GetLastWriteTimeUtc(module)); } [Test] public void ChangedBundleGetsItsOwnDirectoryAndPreservesPreviousBuild() { using var temporary = new TemporaryDirectory(); var old = NativeSupportPackage.ExtractPackage(temporary.Path, Resources("old")); var current = NativeSupportPackage.ExtractPackage(temporary.Path, Resources("current")); Check.That(old != current); Check.Equal("old:dinput8.dll", File.ReadAllText(Path.Combine(old, "dinput8.dll"))); Check.Equal("current:dinput8.dll", File.ReadAllText(Path.Combine(current, "dinput8.dll"))); } [Test] public void MissingAndModifiedCachedFilesAreRepairedFromEmbeddedPayloads() { using var temporary = new TemporaryDirectory(); var resources = Resources(); var directory = NativeSupportPackage.ExtractPackage(temporary.Path, resources); var module = Path.Combine(directory, "DockingControl", "XFEEDInteraction.dll"); var manifest = Path.Combine(directory, "interaction.json"); File.WriteAllText(module, "changed"); File.Delete(manifest); Check.Equal(directory, NativeSupportPackage.ExtractPackage(temporary.Path, resources)); Check.Equal("one:DockingControl/XFEEDInteraction.dll", File.ReadAllText(module)); Check.Equal("one:interaction.json", File.ReadAllText(manifest)); Check.That(!Directory.EnumerateFiles(directory, "*.tmp", SearchOption.AllDirectories).Any()); } [Test] public async Task ConcurrentExtractionProducesOnlyCompleteMatchingPayloads() { using var temporary = new TemporaryDirectory(); var resources = Resources(); var paths = await Task.WhenAll(Enumerable.Range(0, 8) .Select(_ => Task.Run(() => NativeSupportPackage.ExtractPackage(temporary.Path, resources)))); Check.Equal(1, paths.Distinct().Count()); foreach (var pair in resources) Check.Equal(Encoding.UTF8.GetString(pair.Value), File.ReadAllText(Path.Combine(paths[0], pair.Key))); Check.That(!Directory.EnumerateFiles(paths[0], "*.tmp", SearchOption.AllDirectories).Any()); } [Test] public void IncompleteEmptyOrUnexpectedResourcesAreRejectedBeforeExtraction() { using var temporary = new TemporaryDirectory(); var resources = Resources(); resources.Remove("dinput8.dll"); Check.Throws(() => NativeSupportPackage.ExtractPackage(temporary.Path, resources)); resources["../dinput8.dll"] = Encoding.UTF8.GetBytes("unexpected"); Check.Throws(() => NativeSupportPackage.ExtractPackage(temporary.Path, resources)); resources = Resources(); resources["dinput8.dll"] = []; Check.Throws(() => NativeSupportPackage.ExtractPackage(temporary.Path, resources)); Check.That(!Directory.EnumerateFileSystemEntries(temporary.Path).Any()); } }